2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2023-01-05 19:41:06 +08:00
|
|
|
* Copyright (C) 2018-2023 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-18 15:11:08 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/context/context.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
2020-02-24 20:10:44 +08:00
|
|
|
#include "shared/source/built_ins/built_ins.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/command_stream/command_stream_receiver.h"
|
|
|
|
#include "shared/source/compiler_interface/compiler_interface.h"
|
|
|
|
#include "shared/source/debug_settings/debug_settings_manager.h"
|
2022-12-07 19:51:44 +08:00
|
|
|
#include "shared/source/device/sub_device.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/get_info.h"
|
2023-02-06 17:05:43 +08:00
|
|
|
#include "shared/source/helpers/hw_info.h"
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/helpers/ptr_math.h"
|
|
|
|
#include "shared/source/memory_manager/deferred_deleter.h"
|
|
|
|
#include "shared/source/memory_manager/memory_manager.h"
|
|
|
|
#include "shared/source/memory_manager/unified_memory_manager.h"
|
2023-05-13 00:51:52 +08:00
|
|
|
#include "shared/source/utilities/buffer_pool_allocator.inl"
|
2023-01-05 19:41:06 +08:00
|
|
|
#include "shared/source/utilities/heap_allocator.h"
|
2023-01-20 00:11:39 +08:00
|
|
|
#include "shared/source/utilities/tag_allocator.h"
|
2020-02-24 17:22:30 +08:00
|
|
|
|
2020-03-20 18:15:25 +08:00
|
|
|
#include "opencl/source/cl_device/cl_device.h"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/command_queue/command_queue.h"
|
2020-03-17 19:37:38 +08:00
|
|
|
#include "opencl/source/execution_environment/cl_execution_environment.h"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/gtpin/gtpin_notify.h"
|
2023-01-09 19:05:21 +08:00
|
|
|
#include "opencl/source/helpers/cl_validators.h"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/helpers/get_info_status_mapper.h"
|
|
|
|
#include "opencl/source/helpers/surface_formats.h"
|
2023-01-11 01:16:08 +08:00
|
|
|
#include "opencl/source/mem_obj/buffer.h"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/mem_obj/image.h"
|
|
|
|
#include "opencl/source/platform/platform.h"
|
2023-01-25 18:43:07 +08:00
|
|
|
#include "opencl/source/sharings/sharing.h"
|
2020-02-23 05:50:57 +08:00
|
|
|
#include "opencl/source/sharings/sharing_factory.h"
|
2019-02-27 18:39:32 +08:00
|
|
|
|
|
|
|
#include "d3d_sharing_functions.h"
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
#include <algorithm>
|
|
|
|
#include <memory>
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
namespace NEO {
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
Context::Context(
|
|
|
|
void(CL_CALLBACK *funcNotify)(const char *, const void *, size_t, void *),
|
|
|
|
void *data) {
|
|
|
|
contextCallback = funcNotify;
|
|
|
|
userData = data;
|
|
|
|
sharingFunctions.resize(SharingType::MAX_SHARING_VALUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
Context::~Context() {
|
2022-05-19 20:28:33 +08:00
|
|
|
gtpinNotifyContextDestroy((cl_context)this);
|
2023-03-24 20:37:05 +08:00
|
|
|
|
2023-01-20 00:11:39 +08:00
|
|
|
if (multiRootDeviceTimestampPacketAllocator.get() != nullptr) {
|
|
|
|
multiRootDeviceTimestampPacketAllocator.reset();
|
|
|
|
}
|
2023-03-24 20:37:05 +08:00
|
|
|
|
2022-12-12 23:06:59 +08:00
|
|
|
if (smallBufferPoolAllocator.isAggregatedSmallBuffersEnabled(this)) {
|
2022-10-11 21:16:40 +08:00
|
|
|
smallBufferPoolAllocator.releaseSmallBufferPool();
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
delete[] properties;
|
2020-10-29 17:21:29 +08:00
|
|
|
|
|
|
|
for (auto rootDeviceIndex = 0u; rootDeviceIndex < specialQueues.size(); rootDeviceIndex++) {
|
|
|
|
if (specialQueues[rootDeviceIndex]) {
|
|
|
|
delete specialQueues[rootDeviceIndex];
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
if (svmAllocsManager) {
|
2022-12-02 15:25:45 +08:00
|
|
|
svmAllocsManager->trimUSMDeviceAllocCache();
|
2017-12-21 07:45:38 +08:00
|
|
|
delete svmAllocsManager;
|
|
|
|
}
|
|
|
|
if (driverDiagnostics) {
|
|
|
|
delete driverDiagnostics;
|
|
|
|
}
|
|
|
|
if (memoryManager && memoryManager->isAsyncDeleterEnabled()) {
|
|
|
|
memoryManager->getDeferredDeleter()->removeClient();
|
|
|
|
}
|
2020-11-10 23:48:18 +08:00
|
|
|
destructorCallbacks.invoke(this);
|
2018-06-27 21:53:35 +08:00
|
|
|
for (auto &device : devices) {
|
|
|
|
device->decRefInternal();
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-09-08 01:44:29 +08:00
|
|
|
cl_int Context::setDestructorCallback(void(CL_CALLBACK *funcNotify)(cl_context, void *),
|
|
|
|
void *userData) {
|
|
|
|
std::unique_lock<std::mutex> theLock(mtx);
|
2020-11-10 23:48:18 +08:00
|
|
|
destructorCallbacks.add(funcNotify, userData);
|
2020-09-08 01:44:29 +08:00
|
|
|
return CL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-10-18 23:07:01 +08:00
|
|
|
cl_int Context::tryGetExistingHostPtrAllocation(const void *ptr,
|
|
|
|
size_t size,
|
|
|
|
uint32_t rootDeviceIndex,
|
|
|
|
GraphicsAllocation *&allocation,
|
|
|
|
InternalMemoryType &memoryType,
|
|
|
|
bool &isCpuCopyAllowed) {
|
2021-11-08 20:06:22 +08:00
|
|
|
cl_int retVal = tryGetExistingSvmAllocation(ptr, size, rootDeviceIndex, allocation, memoryType, isCpuCopyAllowed);
|
|
|
|
if (retVal != CL_SUCCESS || allocation != nullptr) {
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
retVal = tryGetExistingMapAllocation(ptr, size, allocation);
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl_int Context::tryGetExistingSvmAllocation(const void *ptr,
|
|
|
|
size_t size,
|
|
|
|
uint32_t rootDeviceIndex,
|
|
|
|
GraphicsAllocation *&allocation,
|
|
|
|
InternalMemoryType &memoryType,
|
|
|
|
bool &isCpuCopyAllowed) {
|
2021-10-18 23:07:01 +08:00
|
|
|
if (getSVMAllocsManager()) {
|
|
|
|
SvmAllocationData *svmEntry = getSVMAllocsManager()->getSVMAlloc(ptr);
|
|
|
|
if (svmEntry) {
|
|
|
|
memoryType = svmEntry->memoryType;
|
|
|
|
if ((svmEntry->gpuAllocations.getGraphicsAllocation(rootDeviceIndex)->getGpuAddress() + svmEntry->size) < (castToUint64(ptr) + size)) {
|
|
|
|
return CL_INVALID_OPERATION;
|
|
|
|
}
|
|
|
|
allocation = svmEntry->cpuAllocation ? svmEntry->cpuAllocation : svmEntry->gpuAllocations.getGraphicsAllocation(rootDeviceIndex);
|
|
|
|
if (isCpuCopyAllowed) {
|
2023-12-13 18:09:37 +08:00
|
|
|
if (svmEntry->memoryType == InternalMemoryType::deviceUnifiedMemory) {
|
2021-10-18 23:07:01 +08:00
|
|
|
isCpuCopyAllowed = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-08 20:06:22 +08:00
|
|
|
return CL_SUCCESS;
|
|
|
|
}
|
2021-10-18 23:07:01 +08:00
|
|
|
|
2021-11-08 20:06:22 +08:00
|
|
|
cl_int Context::tryGetExistingMapAllocation(const void *ptr,
|
|
|
|
size_t size,
|
|
|
|
GraphicsAllocation *&allocation) {
|
2021-10-18 23:07:01 +08:00
|
|
|
if (MapInfo mapInfo = {}; mapOperationsStorage.getInfoForHostPtr(ptr, size, mapInfo)) {
|
|
|
|
if (mapInfo.graphicsAllocation) {
|
|
|
|
allocation = mapInfo.graphicsAllocation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return CL_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2022-04-07 21:09:40 +08:00
|
|
|
const RootDeviceIndicesContainer &Context::getRootDeviceIndices() const {
|
2020-09-08 17:19:57 +08:00
|
|
|
return rootDeviceIndices;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t Context::getMaxRootDeviceIndex() const {
|
|
|
|
return maxRootDeviceIndex;
|
|
|
|
}
|
|
|
|
|
2020-10-29 17:21:29 +08:00
|
|
|
CommandQueue *Context::getSpecialQueue(uint32_t rootDeviceIndex) {
|
|
|
|
return specialQueues[rootDeviceIndex];
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-10-29 17:21:29 +08:00
|
|
|
void Context::setSpecialQueue(CommandQueue *commandQueue, uint32_t rootDeviceIndex) {
|
|
|
|
specialQueues[rootDeviceIndex] = commandQueue;
|
2018-01-05 18:33:30 +08:00
|
|
|
}
|
2020-10-29 17:21:29 +08:00
|
|
|
void Context::overrideSpecialQueueAndDecrementRefCount(CommandQueue *commandQueue, uint32_t rootDeviceIndex) {
|
|
|
|
setSpecialQueue(commandQueue, rootDeviceIndex);
|
2018-01-05 18:33:30 +08:00
|
|
|
commandQueue->setIsSpecialCommandQueue(true);
|
2022-07-24 12:21:16 +08:00
|
|
|
// decrement ref count that special queue added
|
2018-01-05 18:33:30 +08:00
|
|
|
this->decRefInternal();
|
2017-12-21 07:45:38 +08:00
|
|
|
};
|
|
|
|
|
2019-07-17 23:45:52 +08:00
|
|
|
bool Context::areMultiStorageAllocationsPreferred() {
|
2019-06-13 16:08:53 +08:00
|
|
|
return this->contextType != ContextType::CONTEXT_TYPE_SPECIALIZED;
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
bool Context::createImpl(const cl_context_properties *properties,
|
2020-01-14 21:32:11 +08:00
|
|
|
const ClDeviceVector &inputDevices,
|
2017-12-21 07:45:38 +08:00
|
|
|
void(CL_CALLBACK *funcNotify)(const char *, const void *, size_t, void *),
|
|
|
|
void *data, cl_int &errcodeRet) {
|
|
|
|
|
|
|
|
auto propertiesCurrent = properties;
|
|
|
|
bool interopUserSync = false;
|
2018-03-02 20:39:22 +08:00
|
|
|
int32_t driverDiagnosticsUsed = -1;
|
2017-12-21 07:45:38 +08:00
|
|
|
auto sharingBuilder = sharingFactory.build();
|
|
|
|
|
|
|
|
std::unique_ptr<DriverDiagnostics> driverDiagnostics;
|
|
|
|
while (propertiesCurrent && *propertiesCurrent) {
|
|
|
|
errcodeRet = CL_SUCCESS;
|
|
|
|
|
|
|
|
auto propertyType = propertiesCurrent[0];
|
|
|
|
auto propertyValue = propertiesCurrent[1];
|
|
|
|
propertiesCurrent += 2;
|
|
|
|
|
|
|
|
switch (propertyType) {
|
2021-03-30 21:15:59 +08:00
|
|
|
case CL_CONTEXT_PLATFORM:
|
|
|
|
break;
|
2017-12-21 07:45:38 +08:00
|
|
|
case CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL:
|
2018-03-02 20:39:22 +08:00
|
|
|
driverDiagnosticsUsed = static_cast<int32_t>(propertyValue);
|
2017-12-21 07:45:38 +08:00
|
|
|
break;
|
|
|
|
case CL_CONTEXT_INTEROP_USER_SYNC:
|
|
|
|
interopUserSync = propertyValue > 0;
|
|
|
|
break;
|
|
|
|
default:
|
2020-10-29 23:26:52 +08:00
|
|
|
if (!sharingBuilder->processProperties(propertyType, propertyValue)) {
|
|
|
|
errcodeRet = CL_INVALID_PROPERTY;
|
2018-11-13 17:23:12 +08:00
|
|
|
return false;
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto numProperties = ptrDiff(propertiesCurrent, properties) / sizeof(cl_context_properties);
|
|
|
|
cl_context_properties *propertiesNew = nullptr;
|
|
|
|
|
|
|
|
// copy the user properties if there are any
|
|
|
|
if (numProperties) {
|
|
|
|
propertiesNew = new cl_context_properties[numProperties + 1];
|
|
|
|
memcpy_s(propertiesNew, (numProperties + 1) * sizeof(cl_context_properties), properties, numProperties * sizeof(cl_context_properties));
|
|
|
|
propertiesNew[numProperties] = 0;
|
|
|
|
numProperties++;
|
|
|
|
}
|
|
|
|
|
2023-11-30 16:32:25 +08:00
|
|
|
if (debugManager.flags.PrintDriverDiagnostics.get() != -1) {
|
|
|
|
driverDiagnosticsUsed = debugManager.flags.PrintDriverDiagnostics.get();
|
2018-03-02 20:39:22 +08:00
|
|
|
}
|
|
|
|
if (driverDiagnosticsUsed >= 0) {
|
|
|
|
driverDiagnostics.reset(new DriverDiagnostics((cl_diagnostics_verbose_level)driverDiagnosticsUsed));
|
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
this->numProperties = numProperties;
|
|
|
|
this->properties = propertiesNew;
|
|
|
|
this->setInteropUserSyncEnabled(interopUserSync);
|
|
|
|
|
|
|
|
if (!sharingBuilder->finalizeProperties(*this, errcodeRet)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-04-28 00:41:15 +08:00
|
|
|
bool containsDeviceWithSubdevices = false;
|
2020-09-08 17:19:57 +08:00
|
|
|
for (const auto &device : inputDevices) {
|
2023-06-12 21:52:45 +08:00
|
|
|
rootDeviceIndices.pushUnique(device->getRootDeviceIndex());
|
2021-09-01 00:49:46 +08:00
|
|
|
containsDeviceWithSubdevices |= device->getNumGenericSubDevices() > 1;
|
2020-09-08 17:19:57 +08:00
|
|
|
}
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
this->driverDiagnostics = driverDiagnostics.release();
|
2023-11-30 16:32:25 +08:00
|
|
|
if (rootDeviceIndices.size() > 1 && containsDeviceWithSubdevices && !debugManager.flags.EnableMultiRootDeviceContexts.get()) {
|
2021-04-28 00:41:15 +08:00
|
|
|
DEBUG_BREAK_IF("No support for context with multiple devices with subdevices");
|
2020-09-08 17:19:57 +08:00
|
|
|
errcodeRet = CL_OUT_OF_HOST_MEMORY;
|
|
|
|
return false;
|
2020-04-10 21:45:44 +08:00
|
|
|
}
|
2020-09-08 17:19:57 +08:00
|
|
|
|
2020-10-29 17:21:29 +08:00
|
|
|
devices = inputDevices;
|
2020-09-28 19:11:58 +08:00
|
|
|
for (auto &rootDeviceIndex : rootDeviceIndices) {
|
|
|
|
DeviceBitfield deviceBitfield{};
|
|
|
|
for (const auto &pDevice : devices) {
|
|
|
|
if (pDevice->getRootDeviceIndex() == rootDeviceIndex) {
|
|
|
|
deviceBitfield |= pDevice->getDeviceBitfield();
|
|
|
|
}
|
2023-01-13 18:36:23 +08:00
|
|
|
for (auto &engine : pDevice->getDevice().getAllEngines()) {
|
|
|
|
engine.commandStreamReceiver->ensureTagAllocationForRootDeviceIndex(rootDeviceIndex);
|
|
|
|
}
|
2020-09-28 19:11:58 +08:00
|
|
|
}
|
|
|
|
deviceBitfields.insert({rootDeviceIndex, deviceBitfield});
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
if (devices.size() > 0) {
|
2020-09-08 17:19:57 +08:00
|
|
|
maxRootDeviceIndex = *std::max_element(rootDeviceIndices.begin(), rootDeviceIndices.end(), std::less<uint32_t const>());
|
2020-10-29 17:21:29 +08:00
|
|
|
specialQueues.resize(maxRootDeviceIndex + 1u);
|
2018-07-31 14:38:50 +08:00
|
|
|
auto device = this->getDevice(0);
|
|
|
|
this->memoryManager = device->getMemoryManager();
|
2017-12-21 07:45:38 +08:00
|
|
|
if (memoryManager->isAsyncDeleterEnabled()) {
|
|
|
|
memoryManager->getDeferredDeleter()->addClient();
|
|
|
|
}
|
|
|
|
|
2020-02-12 18:27:28 +08:00
|
|
|
bool anySvmSupport = false;
|
|
|
|
for (auto &device : devices) {
|
|
|
|
device->incRefInternal();
|
|
|
|
anySvmSupport |= device->getHardwareInfo().capabilityTable.ftrSvm;
|
|
|
|
}
|
|
|
|
|
2021-03-08 20:27:14 +08:00
|
|
|
setupContextType();
|
2020-02-12 18:27:28 +08:00
|
|
|
if (anySvmSupport) {
|
2021-03-08 20:27:14 +08:00
|
|
|
this->svmAllocsManager = new SVMAllocsManager(this->memoryManager,
|
|
|
|
this->areMultiStorageAllocationsPreferred());
|
2020-02-12 18:27:28 +08:00
|
|
|
}
|
2018-06-27 21:53:35 +08:00
|
|
|
}
|
|
|
|
|
2020-10-29 17:21:29 +08:00
|
|
|
for (auto &device : devices) {
|
|
|
|
if (!specialQueues[device->getRootDeviceIndex()]) {
|
2022-05-10 01:40:30 +08:00
|
|
|
auto commandQueue = CommandQueue::create(this, device, nullptr, true, errcodeRet); // NOLINT(clang-analyzer-cplusplus.NewDelete)
|
2020-10-29 17:21:29 +08:00
|
|
|
DEBUG_BREAK_IF(commandQueue == nullptr);
|
|
|
|
overrideSpecialQueueAndDecrementRefCount(commandQueue, device->getRootDeviceIndex());
|
|
|
|
}
|
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl_int Context::getInfo(cl_context_info paramName, size_t paramValueSize,
|
|
|
|
void *paramValue, size_t *paramValueSizeRet) {
|
|
|
|
cl_int retVal;
|
2020-05-18 22:13:59 +08:00
|
|
|
size_t valueSize = GetInfo::invalidSourceSize;
|
2017-12-21 07:45:38 +08:00
|
|
|
const void *pValue = nullptr;
|
|
|
|
cl_uint numDevices;
|
|
|
|
cl_uint refCount = 0;
|
|
|
|
std::vector<cl_device_id> devIDs;
|
|
|
|
auto callGetinfo = true;
|
|
|
|
|
|
|
|
switch (paramName) {
|
|
|
|
case CL_CONTEXT_DEVICES:
|
|
|
|
valueSize = devices.size() * sizeof(cl_device_id);
|
|
|
|
devices.toDeviceIDs(devIDs);
|
|
|
|
pValue = devIDs.data();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_CONTEXT_NUM_DEVICES:
|
|
|
|
numDevices = (cl_uint)(devices.size());
|
|
|
|
valueSize = sizeof(numDevices);
|
|
|
|
pValue = &numDevices;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_CONTEXT_PROPERTIES:
|
|
|
|
valueSize = this->numProperties * sizeof(cl_context_properties);
|
|
|
|
pValue = this->properties;
|
|
|
|
if (valueSize == 0) {
|
|
|
|
callGetinfo = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CL_CONTEXT_REFERENCE_COUNT:
|
|
|
|
refCount = static_cast<cl_uint>(this->getReference());
|
|
|
|
valueSize = sizeof(refCount);
|
|
|
|
pValue = &refCount;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
pValue = getOsContextInfo(paramName, &valueSize);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-12-13 17:17:24 +08:00
|
|
|
GetInfoStatus getInfoStatus = GetInfoStatus::success;
|
2017-12-21 07:45:38 +08:00
|
|
|
if (callGetinfo) {
|
2020-05-18 22:13:59 +08:00
|
|
|
getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, pValue, valueSize);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2020-05-18 22:13:59 +08:00
|
|
|
retVal = changeGetInfoStatusToCLResultType(getInfoStatus);
|
|
|
|
GetInfo::setParamValueReturnSize(paramValueSizeRet, valueSize, getInfoStatus);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t Context::getNumDevices() const {
|
|
|
|
return devices.size();
|
|
|
|
}
|
|
|
|
|
2021-03-30 01:06:29 +08:00
|
|
|
bool Context::containsMultipleSubDevices(uint32_t rootDeviceIndex) const {
|
|
|
|
return deviceBitfields.at(rootDeviceIndex).count() > 1;
|
2019-10-15 19:58:22 +08:00
|
|
|
}
|
|
|
|
|
2020-01-20 22:46:52 +08:00
|
|
|
ClDevice *Context::getDevice(size_t deviceOrdinal) const {
|
2020-01-14 21:32:11 +08:00
|
|
|
return (ClDevice *)devices[deviceOrdinal];
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
cl_int Context::getSupportedImageFormats(
|
|
|
|
Device *device,
|
|
|
|
cl_mem_flags flags,
|
|
|
|
cl_mem_object_type imageType,
|
|
|
|
cl_uint numEntries,
|
|
|
|
cl_image_format *imageFormats,
|
|
|
|
cl_uint *numImageFormatsReturned) {
|
2018-01-31 21:01:59 +08:00
|
|
|
size_t numImageFormats = 0;
|
2020-04-20 18:22:53 +08:00
|
|
|
|
2020-03-06 01:13:32 +08:00
|
|
|
const bool nv12ExtensionEnabled = device->getSpecializedDevice<ClDevice>()->getDeviceInfo().nv12Extension;
|
|
|
|
const bool packedYuvExtensionEnabled = device->getSpecializedDevice<ClDevice>()->getDeviceInfo().packedYuvExtension;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2020-01-09 00:29:15 +08:00
|
|
|
auto appendImageFormats = [&](ArrayRef<const ClSurfaceFormatInfo> formats) {
|
2018-09-11 19:08:29 +08:00
|
|
|
if (imageFormats) {
|
|
|
|
size_t offset = numImageFormats;
|
|
|
|
for (size_t i = 0; i < formats.size() && offset < numEntries; ++i) {
|
2023-04-27 17:50:55 +08:00
|
|
|
imageFormats[offset++] = formats[i].oclImageFormat;
|
2018-01-31 21:01:59 +08:00
|
|
|
}
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
numImageFormats += formats.size();
|
|
|
|
};
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-09-11 19:08:29 +08:00
|
|
|
if (flags & CL_MEM_READ_ONLY) {
|
2020-04-30 21:47:43 +08:00
|
|
|
if (this->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features) {
|
2020-01-10 16:48:09 +08:00
|
|
|
appendImageFormats(SurfaceFormats::readOnly20());
|
|
|
|
} else {
|
|
|
|
appendImageFormats(SurfaceFormats::readOnly12());
|
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
if (Image::isImage2d(imageType) && nv12ExtensionEnabled) {
|
|
|
|
appendImageFormats(SurfaceFormats::planarYuv());
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
if (Image::isImage2dOr2dArray(imageType)) {
|
|
|
|
appendImageFormats(SurfaceFormats::readOnlyDepth());
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
if (Image::isImage2d(imageType) && packedYuvExtensionEnabled) {
|
|
|
|
appendImageFormats(SurfaceFormats::packedYuv());
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
} else if (flags & CL_MEM_WRITE_ONLY) {
|
|
|
|
appendImageFormats(SurfaceFormats::writeOnly());
|
|
|
|
if (Image::isImage2dOr2dArray(imageType)) {
|
|
|
|
appendImageFormats(SurfaceFormats::readWriteDepth());
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
} else if (nv12ExtensionEnabled && (flags & CL_MEM_NO_ACCESS_INTEL)) {
|
2020-04-30 21:47:43 +08:00
|
|
|
if (this->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features) {
|
2020-01-10 16:48:09 +08:00
|
|
|
appendImageFormats(SurfaceFormats::readOnly20());
|
|
|
|
} else {
|
|
|
|
appendImageFormats(SurfaceFormats::readOnly12());
|
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
if (Image::isImage2d(imageType)) {
|
|
|
|
appendImageFormats(SurfaceFormats::planarYuv());
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
} else {
|
|
|
|
appendImageFormats(SurfaceFormats::readWrite());
|
|
|
|
if (Image::isImage2dOr2dArray(imageType)) {
|
|
|
|
appendImageFormats(SurfaceFormats::readWriteDepth());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (numImageFormatsReturned) {
|
2018-01-31 21:01:59 +08:00
|
|
|
*numImageFormatsReturned = static_cast<cl_uint>(numImageFormats);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
return CL_SUCCESS;
|
|
|
|
}
|
2018-09-11 19:08:29 +08:00
|
|
|
|
2020-03-24 22:05:12 +08:00
|
|
|
bool Context::isDeviceAssociated(const ClDevice &clDevice) const {
|
2020-03-30 22:54:33 +08:00
|
|
|
for (const auto &pDevice : devices) {
|
|
|
|
if (pDevice == &clDevice) {
|
2020-03-24 22:05:12 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-03-30 22:54:33 +08:00
|
|
|
ClDevice *Context::getSubDeviceByIndex(uint32_t subDeviceIndex) const {
|
|
|
|
|
|
|
|
auto isExpectedSubDevice = [subDeviceIndex](ClDevice *pClDevice) -> bool {
|
|
|
|
bool isSubDevice = (pClDevice->getDeviceInfo().parentDevice != nullptr);
|
|
|
|
if (isSubDevice == false) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto &subDevice = static_cast<SubDevice &>(pClDevice->getDevice());
|
|
|
|
return (subDevice.getSubDeviceIndex() == subDeviceIndex);
|
|
|
|
};
|
|
|
|
|
|
|
|
auto foundDeviceIterator = std::find_if(devices.begin(), devices.end(), isExpectedSubDevice);
|
|
|
|
return (foundDeviceIterator != devices.end() ? *foundDeviceIterator : nullptr);
|
|
|
|
}
|
|
|
|
|
2020-04-28 17:33:39 +08:00
|
|
|
AsyncEventsHandler &Context::getAsyncEventsHandler() const {
|
2020-03-17 19:37:38 +08:00
|
|
|
return *static_cast<ClExecutionEnvironment *>(devices[0]->getExecutionEnvironment())->getAsyncEventsHandler();
|
|
|
|
}
|
2020-04-28 17:33:39 +08:00
|
|
|
|
2020-09-28 19:11:58 +08:00
|
|
|
DeviceBitfield Context::getDeviceBitfieldForAllocation(uint32_t rootDeviceIndex) const {
|
|
|
|
return deviceBitfields.at(rootDeviceIndex);
|
2020-04-28 17:33:39 +08:00
|
|
|
}
|
2020-05-04 20:38:11 +08:00
|
|
|
|
|
|
|
void Context::setupContextType() {
|
|
|
|
if (contextType == ContextType::CONTEXT_TYPE_DEFAULT) {
|
|
|
|
if (devices.size() > 1) {
|
|
|
|
for (const auto &pDevice : devices) {
|
|
|
|
if (!pDevice->getDeviceInfo().parentDevice) {
|
|
|
|
contextType = ContextType::CONTEXT_TYPE_UNRESTRICTIVE;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (devices[0]->getDeviceInfo().parentDevice) {
|
|
|
|
contextType = ContextType::CONTEXT_TYPE_SPECIALIZED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-30 21:15:59 +08:00
|
|
|
Platform *Context::getPlatformFromProperties(const cl_context_properties *properties, cl_int &errcode) {
|
|
|
|
errcode = CL_SUCCESS;
|
|
|
|
auto propertiesCurrent = properties;
|
|
|
|
while (propertiesCurrent && *propertiesCurrent) {
|
|
|
|
auto propertyType = propertiesCurrent[0];
|
|
|
|
auto propertyValue = propertiesCurrent[1];
|
|
|
|
propertiesCurrent += 2;
|
|
|
|
if (CL_CONTEXT_PLATFORM == propertyType) {
|
|
|
|
Platform *pPlatform = nullptr;
|
2022-05-16 22:06:56 +08:00
|
|
|
errcode = validateObject(withCastToInternal(reinterpret_cast<cl_platform_id>(propertyValue), &pPlatform));
|
2021-03-30 21:15:59 +08:00
|
|
|
return pPlatform;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
2021-07-07 20:43:54 +08:00
|
|
|
|
|
|
|
bool Context::isSingleDeviceContext() {
|
2022-12-12 23:06:59 +08:00
|
|
|
return getNumDevices() == 1 && devices[0]->getNumGenericSubDevices() == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Context::BufferPoolAllocator::isAggregatedSmallBuffersEnabled(Context *context) const {
|
2022-12-19 20:09:33 +08:00
|
|
|
bool isSupportedForSingleDeviceContexts = false;
|
|
|
|
bool isSupportedForAllContexts = false;
|
|
|
|
if (context->getNumDevices() > 0) {
|
2022-12-29 06:59:37 +08:00
|
|
|
auto &productHelper = context->getDevices()[0]->getProductHelper();
|
2022-12-19 20:09:33 +08:00
|
|
|
isSupportedForSingleDeviceContexts = productHelper.isBufferPoolAllocatorSupported();
|
|
|
|
}
|
|
|
|
|
2023-11-30 16:32:25 +08:00
|
|
|
if (debugManager.flags.ExperimentalSmallBufferPoolAllocator.get() != -1) {
|
|
|
|
isSupportedForSingleDeviceContexts = debugManager.flags.ExperimentalSmallBufferPoolAllocator.get() >= 1;
|
|
|
|
isSupportedForAllContexts = debugManager.flags.ExperimentalSmallBufferPoolAllocator.get() >= 2;
|
2022-12-12 23:06:59 +08:00
|
|
|
}
|
2022-12-19 20:09:33 +08:00
|
|
|
|
|
|
|
return isSupportedForAllContexts ||
|
|
|
|
(isSupportedForSingleDeviceContexts && context->isSingleDeviceContext());
|
2021-07-07 20:43:54 +08:00
|
|
|
}
|
2022-10-11 21:16:40 +08:00
|
|
|
|
feature: add optional onChunkFree callback to AbstractBuffersPool
Instances returned by `getAllocationsVector()` in some cases cannot be
freed (in the `malloc/new` sense) until the `drain()` function invokes
`allocInUse()` on them. Plus, the `chunksToFree` container operates on
pairs `{offset, size}`, not pointers, so such pair cannot be used to
release allocations either.
Provide an optional callback, which can be implemented by the custom
pool derived from `AbstractBuffersPool`. This callback can be used, for
example, to perform actual release of an allocation related to the
currently processed chunk.
Additionally, provide the `drain()` and `tryFreeFromPoolBuffer()`
functions with pool-independent versions and keep the previous versions
as defaults (for allocators with a single pool). The new versions allow
reusing the code for cases when allocator has multiple pools.
In both cases, there was no such needs so far but it arose when working
on `IsaBuffersAllocator`. The latter is coming with future commits, but
the shared code modifications are extracted as an independent step.
Related-To: NEO-7788
Signed-off-by: Maciej Bielski <maciej.bielski@intel.com>
2023-06-29 23:15:50 +08:00
|
|
|
Context::BufferPool::BufferPool(Context *context) : BaseType(context->memoryManager, nullptr) {
|
2022-10-11 21:16:40 +08:00
|
|
|
static constexpr cl_mem_flags flags{};
|
|
|
|
[[maybe_unused]] cl_int errcodeRet{};
|
2022-11-21 19:03:05 +08:00
|
|
|
Buffer::AdditionalBufferCreateArgs bufferCreateArgs{};
|
|
|
|
bufferCreateArgs.doNotProvidePerformanceHints = true;
|
|
|
|
bufferCreateArgs.makeAllocationLockable = true;
|
2023-05-13 00:51:52 +08:00
|
|
|
this->mainStorage.reset(Buffer::create(context,
|
|
|
|
flags,
|
|
|
|
BufferPoolAllocator::aggregatedSmallBuffersPoolSize,
|
|
|
|
nullptr,
|
|
|
|
bufferCreateArgs,
|
|
|
|
errcodeRet));
|
|
|
|
if (this->mainStorage) {
|
|
|
|
this->chunkAllocator.reset(new HeapAllocator(BufferPool::startingOffset,
|
|
|
|
BufferPoolAllocator::aggregatedSmallBuffersPoolSize,
|
|
|
|
BufferPoolAllocator::chunkAlignment));
|
2022-10-11 21:16:40 +08:00
|
|
|
context->decRefInternal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-13 00:51:52 +08:00
|
|
|
const StackVec<NEO::GraphicsAllocation *, 1> &Context::BufferPool::getAllocationsVector() {
|
|
|
|
return this->mainStorage->getMultiGraphicsAllocation().getGraphicsAllocations();
|
|
|
|
}
|
2023-03-24 20:37:05 +08:00
|
|
|
|
2023-05-13 00:51:52 +08:00
|
|
|
Buffer *Context::BufferPool::allocate(const MemoryProperties &memoryProperties,
|
|
|
|
cl_mem_flags flags,
|
|
|
|
cl_mem_flags_intel flagsIntel,
|
|
|
|
size_t requestedSize,
|
|
|
|
void *hostPtr,
|
|
|
|
cl_int &errcodeRet) {
|
2023-03-24 20:37:05 +08:00
|
|
|
cl_buffer_region bufferRegion{};
|
|
|
|
size_t actualSize = requestedSize;
|
2023-05-13 00:51:52 +08:00
|
|
|
bufferRegion.origin = static_cast<size_t>(this->chunkAllocator->allocate(actualSize));
|
2023-03-24 20:37:05 +08:00
|
|
|
if (bufferRegion.origin == 0) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2023-05-13 00:51:52 +08:00
|
|
|
bufferRegion.origin -= BufferPool::startingOffset;
|
2023-03-24 20:37:05 +08:00
|
|
|
bufferRegion.size = requestedSize;
|
2023-05-13 00:51:52 +08:00
|
|
|
auto bufferFromPool = this->mainStorage->createSubBuffer(flags, flagsIntel, &bufferRegion, errcodeRet);
|
|
|
|
bufferFromPool->createFunction = this->mainStorage->createFunction;
|
2023-03-24 20:37:05 +08:00
|
|
|
bufferFromPool->setSizeInPoolAllocator(actualSize);
|
|
|
|
return bufferFromPool;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Context::BufferPoolAllocator::initAggregatedSmallBuffers(Context *context) {
|
|
|
|
this->context = context;
|
2023-05-13 00:51:52 +08:00
|
|
|
this->addNewBufferPool(Context::BufferPool{this->context});
|
2023-03-24 20:37:05 +08:00
|
|
|
}
|
|
|
|
|
2022-10-11 21:16:40 +08:00
|
|
|
Buffer *Context::BufferPoolAllocator::allocateBufferFromPool(const MemoryProperties &memoryProperties,
|
|
|
|
cl_mem_flags flags,
|
|
|
|
cl_mem_flags_intel flagsIntel,
|
2023-01-04 19:47:05 +08:00
|
|
|
size_t requestedSize,
|
2022-10-11 21:16:40 +08:00
|
|
|
void *hostPtr,
|
|
|
|
cl_int &errcodeRet) {
|
|
|
|
errcodeRet = CL_MEM_OBJECT_ALLOCATION_FAILURE;
|
2023-05-13 00:51:52 +08:00
|
|
|
if (this->bufferPools.empty() ||
|
|
|
|
!this->isSizeWithinThreshold(requestedSize) ||
|
2023-03-24 20:37:05 +08:00
|
|
|
!flagsAllowBufferFromPool(flags, flagsIntel)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto lock = std::unique_lock<std::mutex>(mutex);
|
2023-05-13 00:51:52 +08:00
|
|
|
auto bufferFromPool = this->allocateFromPools(memoryProperties, flags, flagsIntel, requestedSize, hostPtr, errcodeRet);
|
2023-03-24 20:37:05 +08:00
|
|
|
if (bufferFromPool != nullptr) {
|
2022-10-11 21:16:40 +08:00
|
|
|
return bufferFromPool;
|
|
|
|
}
|
2023-03-24 20:37:05 +08:00
|
|
|
|
2023-05-13 00:51:52 +08:00
|
|
|
this->drain();
|
2023-03-24 20:37:05 +08:00
|
|
|
|
2023-05-13 00:51:52 +08:00
|
|
|
bufferFromPool = this->allocateFromPools(memoryProperties, flags, flagsIntel, requestedSize, hostPtr, errcodeRet);
|
2023-03-24 20:37:05 +08:00
|
|
|
if (bufferFromPool != nullptr) {
|
|
|
|
return bufferFromPool;
|
|
|
|
}
|
|
|
|
|
2023-05-13 00:51:52 +08:00
|
|
|
this->addNewBufferPool(BufferPool{this->context});
|
|
|
|
return this->allocateFromPools(memoryProperties, flags, flagsIntel, requestedSize, hostPtr, errcodeRet);
|
2022-10-11 21:16:40 +08:00
|
|
|
}
|
|
|
|
|
2023-03-24 20:37:05 +08:00
|
|
|
Buffer *Context::BufferPoolAllocator::allocateFromPools(const MemoryProperties &memoryProperties,
|
|
|
|
cl_mem_flags flags,
|
|
|
|
cl_mem_flags_intel flagsIntel,
|
|
|
|
size_t requestedSize,
|
|
|
|
void *hostPtr,
|
|
|
|
cl_int &errcodeRet) {
|
2023-05-13 00:51:52 +08:00
|
|
|
for (auto &bufferPoolParent : this->bufferPools) {
|
|
|
|
auto &bufferPool = static_cast<BufferPool &>(bufferPoolParent);
|
2023-03-24 20:37:05 +08:00
|
|
|
auto bufferFromPool = bufferPool.allocate(memoryProperties, flags, flagsIntel, requestedSize, hostPtr, errcodeRet);
|
|
|
|
if (bufferFromPool != nullptr) {
|
|
|
|
return bufferFromPool;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
2022-10-11 21:16:40 +08:00
|
|
|
}
|
2023-03-24 20:37:05 +08:00
|
|
|
|
2023-01-20 00:11:39 +08:00
|
|
|
TagAllocatorBase *Context::getMultiRootDeviceTimestampPacketAllocator() {
|
|
|
|
return multiRootDeviceTimestampPacketAllocator.get();
|
|
|
|
}
|
|
|
|
void Context::setMultiRootDeviceTimestampPacketAllocator(std::unique_ptr<TagAllocatorBase> &allocator) {
|
|
|
|
multiRootDeviceTimestampPacketAllocator = std::move(allocator);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> Context::obtainOwnershipForMultiRootDeviceAllocator() {
|
|
|
|
return std::unique_lock<std::mutex>(multiRootDeviceAllocatorMtx);
|
|
|
|
}
|
2022-10-11 21:16:40 +08:00
|
|
|
|
2023-03-03 21:23:24 +08:00
|
|
|
void Context::setContextAsNonZebin() {
|
|
|
|
this->nonZebinContext = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Context::checkIfContextIsNonZebin() const {
|
|
|
|
return this->nonZebinContext;
|
|
|
|
}
|
|
|
|
|
2019-03-26 18:59:46 +08:00
|
|
|
} // namespace NEO
|