fix(ocl): Add missing tracing mechanism for clCreateSubDevices API call

Related-To: NEO-8898
Signed-off-by: Kacper Nowak <kacper.nowak@intel.com>
This commit is contained in:
Kacper Nowak 2023-09-22 15:22:24 +00:00 committed by Compute-Runtime-Automation
parent 80d0c74605
commit 0f161c1f19
3 changed files with 188 additions and 31 deletions

View File

@ -326,41 +326,50 @@ cl_int CL_API_CALL clCreateSubDevices(cl_device_id inDevice,
cl_uint numDevices,
cl_device_id *outDevices,
cl_uint *numDevicesRet) {
TRACING_ENTER(ClCreateSubDevices, &inDevice, &properties, &numDevices, &outDevices, &numDevicesRet);
cl_int retVal = CL_INVALID_DEVICE;
API_ENTER(&retVal);
do {
ClDevice *pInDevice = castToObject<ClDevice>(inDevice);
if (pInDevice == nullptr) {
break;
}
auto subDevicesCount = pInDevice->getNumSubDevices();
if (subDevicesCount <= 1) {
retVal = CL_DEVICE_PARTITION_FAILED;
break;
}
if ((properties == nullptr) ||
(properties[0] != CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN) ||
((properties[1] != CL_DEVICE_AFFINITY_DOMAIN_NUMA) && (properties[1] != CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE)) ||
(properties[2] != 0)) {
retVal = CL_INVALID_VALUE;
break;
}
ClDevice *pInDevice = castToObject<ClDevice>(inDevice);
if (pInDevice == nullptr) {
return CL_INVALID_DEVICE;
}
auto subDevicesCount = pInDevice->getNumSubDevices();
if (subDevicesCount <= 1) {
return CL_DEVICE_PARTITION_FAILED;
}
if ((properties == nullptr) ||
(properties[0] != CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN) ||
((properties[1] != CL_DEVICE_AFFINITY_DOMAIN_NUMA) && (properties[1] != CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE)) ||
(properties[2] != 0)) {
return CL_INVALID_VALUE;
}
if (numDevicesRet != nullptr) {
*numDevicesRet = subDevicesCount;
}
if (numDevicesRet != nullptr) {
*numDevicesRet = subDevicesCount;
}
if (outDevices == nullptr) {
retVal = CL_SUCCESS;
break;
}
if (outDevices == nullptr) {
return CL_SUCCESS;
}
if (numDevices < subDevicesCount) {
retVal = CL_INVALID_VALUE;
break;
}
if (numDevices < subDevicesCount) {
return CL_INVALID_VALUE;
}
for (uint32_t i = 0; i < subDevicesCount; i++) {
auto pClDevice = pInDevice->getSubDevice(i);
pClDevice->retainApi();
outDevices[i] = pClDevice;
}
return CL_SUCCESS;
for (uint32_t i = 0; i < subDevicesCount; i++) {
auto pClDevice = pInDevice->getSubDevice(i);
pClDevice->retainApi();
outDevices[i] = pClDevice;
}
retVal = CL_SUCCESS;
} while (false);
TRACING_EXIT(ClCreateSubDevices, &retVal);
return retVal;
}
cl_int CL_API_CALL clRetainDevice(cl_device_id device) {

View File

@ -1001,6 +1001,75 @@ class ClCreateKernelsInProgramTracer {
tracing_notify_state_t state = TRACING_NOTIFY_STATE_NOTHING_CALLED;
};
class ClCreateSubDevicesTracer {
public:
ClCreateSubDevicesTracer() {}
void enter(cl_device_id *inDevice,
const cl_device_partition_property **properties,
cl_uint *numDevices,
cl_device_id **outDevices,
cl_uint **numDevicesRet) {
DEBUG_BREAK_IF(state != TRACING_NOTIFY_STATE_NOTHING_CALLED);
params.inDevice = inDevice;
params.properties = properties;
params.numDevices = numDevices;
params.outDevices = outDevices;
params.numDevicesRet = numDevicesRet;
data.site = CL_CALLBACK_SITE_ENTER;
data.correlationId = tracingCorrelationId.fetch_add(1, std::memory_order_acq_rel);
data.functionName = "clCreateSubDevices";
data.functionParams = static_cast<const void *>(&params);
data.functionReturnValue = nullptr;
size_t i = 0;
DEBUG_BREAK_IF(tracingHandle[0] == nullptr);
while (i < TRACING_MAX_HANDLE_COUNT && tracingHandle[i] != nullptr) {
TracingHandle *handle = tracingHandle[i];
DEBUG_BREAK_IF(handle == nullptr);
if (handle->getTracingPoint(CL_FUNCTION_clCreateSubDevices)) {
data.correlationData = correlationData + i;
handle->call(CL_FUNCTION_clCreateSubDevices, &data);
}
++i;
}
state = TRACING_NOTIFY_STATE_ENTER_CALLED;
}
void exit(cl_int *retVal) {
DEBUG_BREAK_IF(state != TRACING_NOTIFY_STATE_ENTER_CALLED);
data.site = CL_CALLBACK_SITE_EXIT;
data.functionReturnValue = retVal;
size_t i = 0;
DEBUG_BREAK_IF(tracingHandle[0] == nullptr);
while (i < TRACING_MAX_HANDLE_COUNT && tracingHandle[i] != nullptr) {
TracingHandle *handle = tracingHandle[i];
DEBUG_BREAK_IF(handle == nullptr);
if (handle->getTracingPoint(CL_FUNCTION_clCreateSubDevices)) {
data.correlationData = correlationData + i;
handle->call(CL_FUNCTION_clCreateSubDevices, &data);
}
++i;
}
state = TRACING_NOTIFY_STATE_EXIT_CALLED;
}
~ClCreateSubDevicesTracer() {
DEBUG_BREAK_IF(state == TRACING_NOTIFY_STATE_ENTER_CALLED);
}
private:
cl_params_clCreateSubDevices params{};
cl_callback_data data{};
uint64_t correlationData[TRACING_MAX_HANDLE_COUNT];
tracing_notify_state_t state = TRACING_NOTIFY_STATE_NOTHING_CALLED;
};
class ClCreatePipeTracer {
public:
ClCreatePipeTracer() {}

View File

@ -349,6 +349,10 @@ struct IntelAllTracingTest : public IntelTracingTest {
functionId = CL_FUNCTION_clCreateSubBuffer;
clCreateSubBuffer(0, 0, 0, 0, 0);
++count;
functionId = CL_FUNCTION_clCreateSubDevices;
clCreateSubDevices(0, 0, 0, 0, 0);
++count;
functionId = CL_FUNCTION_clCreateUserEvent;
clCreateUserEvent(0, 0);
@ -1126,4 +1130,79 @@ TEST_F(IntelClCloneKernelTracingTest, givenCloneKernelCallTracingWhenInvokingCal
clReleaseKernel(clonedKernel);
}
struct IntelClCreateSubDevicesTracingTest : public IntelTracingTest {
public:
void SetUp() override {
IntelTracingTest::setUp();
DebugManager.flags.CreateMultipleSubDevices.set(deviceCount);
device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
status = clCreateTracingHandleINTEL(testedClDevice, callback, this, &handle);
ASSERT_NE(nullptr, handle);
ASSERT_EQ(CL_SUCCESS, status);
status = clSetTracingPointINTEL(handle, CL_FUNCTION_clCreateSubDevices, CL_TRUE);
ASSERT_EQ(CL_SUCCESS, status);
status = clEnableTracingINTEL(handle);
ASSERT_EQ(CL_SUCCESS, status);
}
void TearDown() override {
status = clDisableTracingINTEL(handle);
ASSERT_EQ(CL_SUCCESS, status);
status = clDestroyTracingHandleINTEL(handle);
ASSERT_EQ(CL_SUCCESS, status);
IntelTracingTest::tearDown();
}
void call() {
auto retVal = clCreateSubDevices(device.get(), properties, deviceCount, outDevices, numDevicesRet);
ASSERT_EQ(CL_SUCCESS, retVal);
}
void vcallback(cl_function_id fid, cl_callback_data *callbackData, void *userData) override {
ASSERT_EQ(CL_FUNCTION_clCreateSubDevices, fid);
if (callbackData->site == CL_CALLBACK_SITE_ENTER) {
++enterCount;
} else if (callbackData->site == CL_CALLBACK_SITE_EXIT) {
auto funcParams = reinterpret_cast<const cl_params_clCreateSubDevices *>(callbackData->functionParams); // check at tracing exit, once api call has been executed
EXPECT_EQ(static_cast<cl_device_id>(device.get()), *(funcParams->inDevice));
EXPECT_EQ(2u, *(funcParams->numDevices));
EXPECT_EQ(numDevicesRet[0], *(funcParams->numDevicesRet[0]));
auto outDevicesCallback = *(funcParams->outDevices);
EXPECT_EQ(static_cast<cl_device_id>(device->getSubDevice(0)), outDevicesCallback[0]);
EXPECT_EQ(static_cast<cl_device_id>(device->getSubDevice(1)), outDevicesCallback[1]);
auto propertiesCallback = *(funcParams->properties);
EXPECT_EQ(CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN, propertiesCallback[0]);
EXPECT_EQ(CL_DEVICE_AFFINITY_DOMAIN_NUMA, propertiesCallback[1]);
EXPECT_EQ(0, propertiesCallback[2]);
EXPECT_STREQ("clCreateSubDevices", callbackData->functionName);
EXPECT_EQ(CL_SUCCESS, *reinterpret_cast<cl_int *>(callbackData->functionReturnValue));
++exitCount;
}
}
protected:
DebugManagerStateRestore restorer;
std::unique_ptr<MockClDevice> device;
cl_device_partition_property properties[3] = {CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN, CL_DEVICE_AFFINITY_DOMAIN_NUMA, 0};
cl_uint deviceCount = 2u;
cl_device_id outDevices[2] = {0, 0};
cl_uint numDevicesRet[1] = {0u};
uint16_t enterCount = 0u;
uint16_t exitCount = 0u;
};
TEST_F(IntelClCreateSubDevicesTracingTest, givenCreateSubDevicesCallTracingEnabledWhenInvokingThisCallThenCallIsSuccessfullyTraced) {
call();
EXPECT_EQ(1u, enterCount);
EXPECT_EQ(1u, exitCount);
}
} // namespace ULT