Skip to content

Commit 7be937c

Browse files
Update clCreateSubDevices implementation
Make it possible to get SubDevices from given RootDevice. Resolves: NEO-3977 Change-Id: I9cf06f17b45299009ab6953b9ad7d5cb0bbe848f Signed-off-by: Filip Hazubski <filip.hazubski@intel.com>
1 parent 73dad03 commit 7be937c

File tree

4 files changed

+107
-85
lines changed

4 files changed

+107
-85
lines changed

runtime/api/api.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,17 +251,37 @@ cl_int CL_API_CALL clCreateSubDevices(cl_device_id inDevice,
251251
cl_uint numDevices,
252252
cl_device_id *outDevices,
253253
cl_uint *numDevicesRet) {
254-
TRACING_ENTER(clCreateSubDevices, &inDevice, &properties, &numDevices, &outDevices, &numDevicesRet);
255-
cl_int retVal = CL_INVALID_DEVICE;
256-
API_ENTER(&retVal);
257-
DBG_LOG_INPUTS("inDevice", inDevice,
258-
"properties", properties,
259-
"numDevices", numDevices,
260-
"outDevices:", outDevices,
261-
"numDevicesRet", numDevicesRet);
262254

263-
TRACING_EXIT(clCreateSubDevices, &retVal);
264-
return retVal;
255+
Device *pInDevice = castToObject<Device>(inDevice);
256+
if (pInDevice == nullptr) {
257+
return CL_INVALID_DEVICE;
258+
}
259+
auto subDevicesCount = pInDevice->getNumAvailableDevices();
260+
if (subDevicesCount <= 1) {
261+
return CL_INVALID_DEVICE;
262+
}
263+
if (properties == nullptr || properties[0] != CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN ||
264+
properties[1] != CL_DEVICE_AFFINITY_DOMAIN_NUMA || properties[2] != 0) {
265+
return CL_INVALID_VALUE;
266+
}
267+
268+
if (numDevicesRet != nullptr) {
269+
*numDevicesRet = subDevicesCount;
270+
}
271+
272+
if (outDevices == nullptr) {
273+
return CL_SUCCESS;
274+
}
275+
276+
if (numDevices < subDevicesCount) {
277+
return CL_INVALID_VALUE;
278+
}
279+
280+
for (uint32_t i = 0; i < subDevicesCount; i++) {
281+
outDevices[i] = pInDevice->getDeviceById(i);
282+
}
283+
284+
return CL_SUCCESS;
265285
}
266286

267287
cl_int CL_API_CALL clRetainDevice(cl_device_id device) {

runtime/tracing/tracing_notify.h

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,73 +1502,6 @@ class clCreateSubBufferTracer {
15021502
tracing_notify_state_t state = TRACING_NOTIFY_STATE_NOTHING_CALLED;
15031503
};
15041504

1505-
class clCreateSubDevicesTracer {
1506-
public:
1507-
clCreateSubDevicesTracer() {}
1508-
1509-
void enter(cl_device_id *inDevice,
1510-
const cl_device_partition_property **properties,
1511-
cl_uint *numDevices,
1512-
cl_device_id **outDevices,
1513-
cl_uint **numDevicesRet) {
1514-
DEBUG_BREAK_IF(state != TRACING_NOTIFY_STATE_NOTHING_CALLED);
1515-
1516-
params.inDevice = inDevice;
1517-
params.properties = properties;
1518-
params.numDevices = numDevices;
1519-
params.outDevices = outDevices;
1520-
params.numDevicesRet = numDevicesRet;
1521-
1522-
data.site = CL_CALLBACK_SITE_ENTER;
1523-
data.correlationId = tracingCorrelationId.fetch_add(1, std::memory_order_acq_rel);
1524-
data.functionName = "clCreateSubDevices";
1525-
data.functionParams = static_cast<const void *>(&params);
1526-
data.functionReturnValue = nullptr;
1527-
1528-
DEBUG_BREAK_IF(tracingHandle.size() == 0);
1529-
DEBUG_BREAK_IF(tracingHandle.size() >= TRACING_MAX_HANDLE_COUNT);
1530-
for (size_t i = 0; i < tracingHandle.size(); ++i) {
1531-
TracingHandle *handle = tracingHandle[i];
1532-
DEBUG_BREAK_IF(handle == nullptr);
1533-
if (handle->getTracingPoint(CL_FUNCTION_clCreateSubDevices)) {
1534-
data.correlationData = correlationData + i;
1535-
handle->call(CL_FUNCTION_clCreateSubDevices, &data);
1536-
}
1537-
}
1538-
1539-
state = TRACING_NOTIFY_STATE_ENTER_CALLED;
1540-
}
1541-
1542-
void exit(cl_int *retVal) {
1543-
DEBUG_BREAK_IF(state != TRACING_NOTIFY_STATE_ENTER_CALLED);
1544-
data.site = CL_CALLBACK_SITE_EXIT;
1545-
data.functionReturnValue = retVal;
1546-
1547-
DEBUG_BREAK_IF(tracingHandle.size() == 0);
1548-
DEBUG_BREAK_IF(tracingHandle.size() >= TRACING_MAX_HANDLE_COUNT);
1549-
for (size_t i = 0; i < tracingHandle.size(); ++i) {
1550-
TracingHandle *handle = tracingHandle[i];
1551-
DEBUG_BREAK_IF(handle == nullptr);
1552-
if (handle->getTracingPoint(CL_FUNCTION_clCreateSubDevices)) {
1553-
data.correlationData = correlationData + i;
1554-
handle->call(CL_FUNCTION_clCreateSubDevices, &data);
1555-
}
1556-
}
1557-
1558-
state = TRACING_NOTIFY_STATE_EXIT_CALLED;
1559-
}
1560-
1561-
~clCreateSubDevicesTracer() {
1562-
DEBUG_BREAK_IF(state == TRACING_NOTIFY_STATE_ENTER_CALLED);
1563-
}
1564-
1565-
private:
1566-
cl_params_clCreateSubDevices params;
1567-
cl_callback_data data;
1568-
uint64_t correlationData[TRACING_MAX_HANDLE_COUNT];
1569-
tracing_notify_state_t state = TRACING_NOTIFY_STATE_NOTHING_CALLED;
1570-
};
1571-
15721505
class clCreateUserEventTracer {
15731506
public:
15741507
clCreateUserEventTracer() {}

unit_tests/api/cl_create_sub_devices_tests.inl

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,32 @@
55
*
66
*/
77

8-
#include "cl_api_tests.h"
8+
#include "core/unit_tests/helpers/debug_manager_state_restore.h"
9+
#include "runtime/api/api.h"
10+
#include "test.h"
11+
#include "unit_tests/helpers/variable_backup.h"
912

10-
using namespace NEO;
13+
#include <memory>
1114

12-
typedef api_tests clCreateSubDevicesTests;
15+
using namespace NEO;
1316

1417
namespace ULT {
1518

19+
struct clCreateSubDevicesTests : ::testing::Test {
20+
DebugManagerStateRestore restorer;
21+
VariableBackup<bool> mockDeviceCreateSingleDeviceBackup{&MockDevice::createSingleDevice};
22+
std::unique_ptr<MockDevice> device;
23+
cl_device_partition_property properties[3] = {CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN, CL_DEVICE_AFFINITY_DOMAIN_NUMA, 0};
24+
cl_uint outDevicesCount = 2;
25+
cl_device_id outDevices[2];
26+
27+
void setup(int numberOfDevices) {
28+
DebugManager.flags.CreateMultipleSubDevices.set(numberOfDevices);
29+
mockDeviceCreateSingleDeviceBackup = (numberOfDevices == 1);
30+
device.reset(MockDevice::createWithNewExecutionEnvironment<MockDevice>(*platformDevices));
31+
}
32+
};
33+
1634
TEST_F(clCreateSubDevicesTests, GivenInvalidDeviceWhenCreatingSubDevicesThenInvalidDeviceErrorIsReturned) {
1735
auto retVal = clCreateSubDevices(
1836
nullptr,
@@ -22,4 +40,59 @@ TEST_F(clCreateSubDevicesTests, GivenInvalidDeviceWhenCreatingSubDevicesThenInva
2240
nullptr);
2341
EXPECT_EQ(retVal, CL_INVALID_DEVICE);
2442
}
43+
44+
TEST_F(clCreateSubDevicesTests, GivenDeviceWithoutSubDevicesWhenCreatingSubDevicesThenInvalidDeviceErrorIsReturned) {
45+
setup(1);
46+
47+
auto retVal = clCreateSubDevices(device.get(), nullptr, 0, nullptr, nullptr);
48+
EXPECT_EQ(CL_INVALID_DEVICE, retVal);
49+
}
50+
51+
TEST_F(clCreateSubDevicesTests, GivenInvalidOrUnsupportedPropertiesWhenCreatingSubDevicesThenInvalidValueErrorIsReturned) {
52+
setup(2);
53+
54+
auto retVal = clCreateSubDevices(device.get(), nullptr, 0, nullptr, nullptr);
55+
EXPECT_EQ(CL_INVALID_VALUE, retVal);
56+
57+
properties[0] = 0;
58+
retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, nullptr);
59+
EXPECT_EQ(CL_INVALID_VALUE, retVal);
60+
61+
properties[0] = CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN;
62+
properties[1] = 0;
63+
retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, nullptr);
64+
EXPECT_EQ(CL_INVALID_VALUE, retVal);
65+
66+
properties[1] = CL_DEVICE_AFFINITY_DOMAIN_NUMA;
67+
properties[2] = CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN;
68+
retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, nullptr);
69+
EXPECT_EQ(CL_INVALID_VALUE, retVal);
70+
}
71+
72+
TEST_F(clCreateSubDevicesTests, GivenOutDevicesNullWhenCreatingSubDevicesThenSuccessIsReturned) {
73+
setup(2);
74+
75+
cl_uint returnedOutDeviceCount = 0;
76+
auto retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, &returnedOutDeviceCount);
77+
EXPECT_EQ(CL_SUCCESS, retVal);
78+
EXPECT_EQ(2u, returnedOutDeviceCount);
79+
}
80+
81+
TEST_F(clCreateSubDevicesTests, GivenOutDevicesTooSmallWhenCreatingSubDevicesThenInvalidValueErrorIsReturned) {
82+
setup(2);
83+
84+
outDevicesCount = 1;
85+
auto retVal = clCreateSubDevices(device.get(), properties, outDevicesCount, outDevices, nullptr);
86+
EXPECT_EQ(CL_INVALID_VALUE, retVal);
87+
}
88+
89+
TEST_F(clCreateSubDevicesTests, GivenValidInputWhenCreatingSubDevicesThenSubDevicesAreReturned) {
90+
setup(2);
91+
92+
auto retVal = clCreateSubDevices(device.get(), properties, outDevicesCount, outDevices, nullptr);
93+
EXPECT_EQ(CL_SUCCESS, retVal);
94+
EXPECT_EQ(device->getDeviceById(0), outDevices[0]);
95+
EXPECT_EQ(device->getDeviceById(1), outDevices[1]);
96+
}
97+
2598
} // namespace ULT

unit_tests/api/cl_intel_tracing_tests.inl

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,6 @@ struct IntelAllTracingTest : public IntelTracingTest {
316316
functionId = CL_FUNCTION_clCreateSubBuffer;
317317
clCreateSubBuffer(0, 0, 0, 0, 0);
318318

319-
++count;
320-
functionId = CL_FUNCTION_clCreateSubDevices;
321-
clCreateSubDevices(0, 0, 0, 0, 0);
322-
323319
++count;
324320
functionId = CL_FUNCTION_clCreateUserEvent;
325321
clCreateUserEvent(0, 0);
@@ -864,4 +860,4 @@ TEST_F(IntelClGetDeviceInfoTwoHandlesTracingCollectTest, GeneralTracingCollectio
864860
EXPECT_EQ(2u, exitCount);
865861
}
866862

867-
} // namespace ULT
863+
} // namespace ULT

0 commit comments

Comments
 (0)