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>
This commit is contained in:
Filip Hazubski
2019-12-04 12:45:40 +01:00
committed by sys_ocldev
parent 73dad03c66
commit 7be937c226
4 changed files with 107 additions and 85 deletions

View File

@@ -251,17 +251,37 @@ 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);
DBG_LOG_INPUTS("inDevice", inDevice,
"properties", properties,
"numDevices", numDevices,
"outDevices:", outDevices,
"numDevicesRet", numDevicesRet);
TRACING_EXIT(clCreateSubDevices, &retVal);
return retVal;
Device *pInDevice = castToObject<Device>(inDevice);
if (pInDevice == nullptr) {
return CL_INVALID_DEVICE;
}
auto subDevicesCount = pInDevice->getNumAvailableDevices();
if (subDevicesCount <= 1) {
return CL_INVALID_DEVICE;
}
if (properties == nullptr || properties[0] != CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN ||
properties[1] != CL_DEVICE_AFFINITY_DOMAIN_NUMA || properties[2] != 0) {
return CL_INVALID_VALUE;
}
if (numDevicesRet != nullptr) {
*numDevicesRet = subDevicesCount;
}
if (outDevices == nullptr) {
return CL_SUCCESS;
}
if (numDevices < subDevicesCount) {
return CL_INVALID_VALUE;
}
for (uint32_t i = 0; i < subDevicesCount; i++) {
outDevices[i] = pInDevice->getDeviceById(i);
}
return CL_SUCCESS;
}
cl_int CL_API_CALL clRetainDevice(cl_device_id device) {

View File

@@ -1502,73 +1502,6 @@ class clCreateSubBufferTracer {
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;
DEBUG_BREAK_IF(tracingHandle.size() == 0);
DEBUG_BREAK_IF(tracingHandle.size() >= TRACING_MAX_HANDLE_COUNT);
for (size_t i = 0; i < tracingHandle.size(); ++i) {
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);
}
}
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;
DEBUG_BREAK_IF(tracingHandle.size() == 0);
DEBUG_BREAK_IF(tracingHandle.size() >= TRACING_MAX_HANDLE_COUNT);
for (size_t i = 0; i < tracingHandle.size(); ++i) {
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);
}
}
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 clCreateUserEventTracer {
public:
clCreateUserEventTracer() {}

View File

@@ -5,14 +5,32 @@
*
*/
#include "cl_api_tests.h"
#include "core/unit_tests/helpers/debug_manager_state_restore.h"
#include "runtime/api/api.h"
#include "test.h"
#include "unit_tests/helpers/variable_backup.h"
#include <memory>
using namespace NEO;
typedef api_tests clCreateSubDevicesTests;
namespace ULT {
struct clCreateSubDevicesTests : ::testing::Test {
DebugManagerStateRestore restorer;
VariableBackup<bool> mockDeviceCreateSingleDeviceBackup{&MockDevice::createSingleDevice};
std::unique_ptr<MockDevice> device;
cl_device_partition_property properties[3] = {CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN, CL_DEVICE_AFFINITY_DOMAIN_NUMA, 0};
cl_uint outDevicesCount = 2;
cl_device_id outDevices[2];
void setup(int numberOfDevices) {
DebugManager.flags.CreateMultipleSubDevices.set(numberOfDevices);
mockDeviceCreateSingleDeviceBackup = (numberOfDevices == 1);
device.reset(MockDevice::createWithNewExecutionEnvironment<MockDevice>(*platformDevices));
}
};
TEST_F(clCreateSubDevicesTests, GivenInvalidDeviceWhenCreatingSubDevicesThenInvalidDeviceErrorIsReturned) {
auto retVal = clCreateSubDevices(
nullptr,
@@ -22,4 +40,59 @@ TEST_F(clCreateSubDevicesTests, GivenInvalidDeviceWhenCreatingSubDevicesThenInva
nullptr);
EXPECT_EQ(retVal, CL_INVALID_DEVICE);
}
TEST_F(clCreateSubDevicesTests, GivenDeviceWithoutSubDevicesWhenCreatingSubDevicesThenInvalidDeviceErrorIsReturned) {
setup(1);
auto retVal = clCreateSubDevices(device.get(), nullptr, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_DEVICE, retVal);
}
TEST_F(clCreateSubDevicesTests, GivenInvalidOrUnsupportedPropertiesWhenCreatingSubDevicesThenInvalidValueErrorIsReturned) {
setup(2);
auto retVal = clCreateSubDevices(device.get(), nullptr, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
properties[0] = 0;
retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
properties[0] = CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN;
properties[1] = 0;
retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
properties[1] = CL_DEVICE_AFFINITY_DOMAIN_NUMA;
properties[2] = CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN;
retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST_F(clCreateSubDevicesTests, GivenOutDevicesNullWhenCreatingSubDevicesThenSuccessIsReturned) {
setup(2);
cl_uint returnedOutDeviceCount = 0;
auto retVal = clCreateSubDevices(device.get(), properties, 0, nullptr, &returnedOutDeviceCount);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, returnedOutDeviceCount);
}
TEST_F(clCreateSubDevicesTests, GivenOutDevicesTooSmallWhenCreatingSubDevicesThenInvalidValueErrorIsReturned) {
setup(2);
outDevicesCount = 1;
auto retVal = clCreateSubDevices(device.get(), properties, outDevicesCount, outDevices, nullptr);
EXPECT_EQ(CL_INVALID_VALUE, retVal);
}
TEST_F(clCreateSubDevicesTests, GivenValidInputWhenCreatingSubDevicesThenSubDevicesAreReturned) {
setup(2);
auto retVal = clCreateSubDevices(device.get(), properties, outDevicesCount, outDevices, nullptr);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(device->getDeviceById(0), outDevices[0]);
EXPECT_EQ(device->getDeviceById(1), outDevices[1]);
}
} // namespace ULT

View File

@@ -316,10 +316,6 @@ 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);
@@ -864,4 +860,4 @@ TEST_F(IntelClGetDeviceInfoTwoHandlesTracingCollectTest, GeneralTracingCollectio
EXPECT_EQ(2u, exitCount);
}
} // namespace ULT
} // namespace ULT