Skip to content

Commit 33c1a16

Browse files
Initialize execution environment before creating platform
Related-To: NEO-4208 Change-Id: I3a242bfcc149aad01966693f99fbfc51ba71483d Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
1 parent 9a4d515 commit 33c1a16

28 files changed

+231
-127
lines changed

core/os_interface/device_factory.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ bool DeviceFactory::getDevicesForProductFamilyOverride(size_t &numDevices, Execu
5050

5151
executionEnvironment.calculateMaxOsContextCount();
5252
numDevices = numRootDevices;
53-
DeviceFactory::numDevices = numDevices;
5453
auto csrType = DebugManager.flags.SetCommandStreamReceiver.get();
5554
if (csrType > 0) {
5655
auto &hwHelper = HwHelper::get(hardwareInfo->platform.eRenderCoreFamily);

core/os_interface/device_factory.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@
77

88
#pragma once
99
#include <cstdlib>
10+
#include <memory>
11+
#include <vector>
1012

1113
namespace NEO {
1214

1315
class ExecutionEnvironment;
16+
class HwDeviceId;
1417

18+
bool getDevices(size_t &numDevicesReturned, ExecutionEnvironment &executionEnvironment);
1519
class DeviceFactory {
1620
public:
21+
using HwDeviceIds = std::vector<std::unique_ptr<HwDeviceId>>;
1722
static bool getDevices(size_t &numDevices, ExecutionEnvironment &executionEnvironment);
1823
static bool getDevicesForProductFamilyOverride(size_t &numDevices, ExecutionEnvironment &executionEnvironment);
1924
static void releaseDevices();

core/os_interface/linux/device_factory_linux.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,25 @@
2020
namespace NEO {
2121
size_t DeviceFactory::numDevices = 0;
2222

23-
bool DeviceFactory::getDevices(size_t &numDevices, ExecutionEnvironment &executionEnvironment) {
24-
size_t numRootDevices = 1;
23+
bool DeviceFactory::getDevices(size_t &totalNumRootDevices, ExecutionEnvironment &executionEnvironment) {
2524

25+
HwDeviceIds hwDeviceIds;
26+
27+
size_t numRootDevices = 1u;
2628
if (DebugManager.flags.CreateMultipleRootDevices.get()) {
2729
numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get();
2830
}
31+
for (size_t i = 0; i < numRootDevices; i++) {
32+
auto hwDeviceId = Drm::discoverDevices();
33+
hwDeviceIds.push_back(std::move(hwDeviceId));
34+
}
35+
totalNumRootDevices = numRootDevices;
2936

3037
executionEnvironment.prepareRootDeviceEnvironments(static_cast<uint32_t>(numRootDevices));
3138

32-
for (auto rootDeviceIndex = 0u; rootDeviceIndex < numRootDevices; rootDeviceIndex++) {
33-
auto hwDeviceId = Drm::discoverDevices();
39+
uint32_t rootDeviceIndex = 0u;
40+
41+
for (auto &hwDeviceId : hwDeviceIds) {
3442
Drm *drm = Drm::create(std::move(hwDeviceId), *executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]);
3543
if (!drm) {
3644
return false;
@@ -39,6 +47,7 @@ bool DeviceFactory::getDevices(size_t &numDevices, ExecutionEnvironment &executi
3947
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface = std::make_unique<DrmMemoryOperationsHandler>();
4048
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->osInterface.reset(new OSInterface());
4149
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->osInterface->get()->setDrm(drm);
50+
rootDeviceIndex++;
4251
}
4352

4453
auto hardwareInfo = executionEnvironment.getMutableHardwareInfo();
@@ -47,9 +56,7 @@ bool DeviceFactory::getDevices(size_t &numDevices, ExecutionEnvironment &executi
4756
return false;
4857
}
4958
executionEnvironment.calculateMaxOsContextCount();
50-
51-
numDevices = numRootDevices;
52-
DeviceFactory::numDevices = numDevices;
59+
DeviceFactory::numDevices = numRootDevices;
5360

5461
return true;
5562
}

core/os_interface/windows/device_factory_win.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,43 +19,46 @@ namespace NEO {
1919

2020
extern const HardwareInfo *hardwareInfoTable[IGFX_MAX_PRODUCT];
2121

22-
size_t DeviceFactory::numDevices = 0;
22+
bool DeviceFactory::getDevices(size_t &totalNumRootDevices, ExecutionEnvironment &executionEnvironment) {
23+
HwDeviceIds hwDeviceIds;
24+
totalNumRootDevices = 0;
2325

24-
bool DeviceFactory::getDevices(size_t &numDevices, ExecutionEnvironment &executionEnvironment) {
25-
numDevices = 0;
26-
27-
auto numRootDevices = 1u;
26+
size_t numRootDevices = 1u;
2827
if (DebugManager.flags.CreateMultipleRootDevices.get()) {
2928
numRootDevices = DebugManager.flags.CreateMultipleRootDevices.get();
3029
}
31-
32-
executionEnvironment.prepareRootDeviceEnvironments(static_cast<uint32_t>(numRootDevices));
33-
34-
for (auto rootDeviceIndex = 0u; rootDeviceIndex < numRootDevices; rootDeviceIndex++) {
30+
for (size_t i = 0; i < numRootDevices; i++) {
3531
auto hwDeviceId = Wddm::discoverDevices();
36-
if (!hwDeviceId) {
37-
return false;
32+
if (hwDeviceId) {
33+
hwDeviceIds.push_back(std::move(hwDeviceId));
3834
}
35+
}
36+
if (hwDeviceIds.empty()) {
37+
return false;
38+
}
39+
totalNumRootDevices = numRootDevices;
40+
41+
executionEnvironment.prepareRootDeviceEnvironments(static_cast<uint32_t>(totalNumRootDevices));
42+
43+
uint32_t rootDeviceIndex = 0u;
44+
45+
for (auto &hwDeviceId : hwDeviceIds) {
3946
std::unique_ptr<Wddm> wddm(Wddm::createWddm(std::move(hwDeviceId), *executionEnvironment.rootDeviceEnvironments[rootDeviceIndex].get()));
4047
if (!wddm->init()) {
4148
return false;
4249
}
4350
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->memoryOperationsInterface = std::make_unique<WddmMemoryOperationsHandler>(wddm.get());
4451
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->osInterface = std::make_unique<OSInterface>();
4552
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->osInterface->get()->setWddm(wddm.release());
53+
rootDeviceIndex++;
4654
}
47-
executionEnvironment.calculateMaxOsContextCount();
48-
49-
numDevices = numRootDevices;
50-
DeviceFactory::numDevices = numDevices;
5155

56+
executionEnvironment.calculateMaxOsContextCount();
5257
return true;
5358
}
5459

5560
void DeviceFactory::releaseDevices() {
56-
DeviceFactory::numDevices = 0;
5761
}
58-
5962
} // namespace NEO
6063

6164
#endif

runtime/api/api.cpp

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,31 @@ cl_int CL_API_CALL clGetPlatformIDs(cl_uint numEntries,
7878
break;
7979
}
8080

81-
while (platforms != nullptr) {
82-
auto pPlatform = constructPlatform();
83-
bool ret = pPlatform->initialize();
84-
DEBUG_BREAK_IF(ret != true);
85-
if (!ret) {
81+
static std::mutex mutex;
82+
std::unique_lock<std::mutex> lock(mutex);
83+
if (platformsImpl.empty()) {
84+
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
85+
size_t numRootDevices = 0u;
86+
bool status = getDevices(numRootDevices, *executionEnvironment);
87+
if (!status) {
8688
retVal = CL_OUT_OF_HOST_MEMORY;
8789
break;
8890
}
89-
91+
auto pPlatform = Platform::createFunc(*executionEnvironment.release());
92+
if (!pPlatform->initialize(numRootDevices, 0u)) {
93+
retVal = CL_OUT_OF_HOST_MEMORY;
94+
break;
95+
}
96+
platformsImpl.push_back(std::move(pPlatform));
97+
}
98+
if (platforms) {
9099
// we only have one platform so we can program that directly
91-
platforms[0] = pPlatform;
92-
break;
100+
platforms[0] = platformsImpl[0].get();
93101
}
94102

95103
// we only have a single platform at this time, so return 1 if num_platforms
96104
// is non-nullptr
97-
if (numPlatforms && retVal == CL_SUCCESS) {
105+
if (numPlatforms) {
98106
*numPlatforms = 1;
99107
}
100108
} while (false);
@@ -178,10 +186,13 @@ cl_int CL_API_CALL clGetDeviceIDs(cl_platform_id platform,
178186
break;
179187
}
180188
} else {
181-
pPlatform = constructPlatform();
182-
bool ret = pPlatform->initialize();
183-
DEBUG_BREAK_IF(ret != true);
184-
UNUSED_VARIABLE(ret);
189+
cl_uint numPlatforms = 0u;
190+
retVal = clGetPlatformIDs(0, nullptr, &numPlatforms);
191+
if (numPlatforms == 0u) {
192+
retVal = CL_DEVICE_NOT_FOUND;
193+
break;
194+
}
195+
pPlatform = platformsImpl[0].get();
185196
}
186197

187198
DEBUG_BREAK_IF(pPlatform->isInitialized() != true);

runtime/platform/platform.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ namespace NEO {
3636

3737
std::vector<std::unique_ptr<Platform>> platformsImpl;
3838

39-
bool getDevices(size_t &numDevicesReturned, ExecutionEnvironment &executionEnvironment);
40-
4139
Platform *platform() {
4240
if (platformsImpl.empty()) {
4341
return nullptr;
@@ -122,8 +120,7 @@ cl_int Platform::getInfo(cl_platform_info paramName,
122120
return retVal;
123121
}
124122

125-
bool Platform::initialize() {
126-
size_t numDevicesReturned = 0;
123+
bool Platform::initialize(size_t numDevices, uint32_t firstRootDeviceIndex) {
127124

128125
TakeOwnershipWrapper<Platform> platformOwnership(*this);
129126

@@ -136,11 +133,7 @@ bool Platform::initialize() {
136133
this->initializationLoopHelper();
137134
}
138135

139-
state = NEO::getDevices(numDevicesReturned, executionEnvironment) ? StateIniting : StateNone;
140-
141-
if (state == StateNone) {
142-
return false;
143-
}
136+
state = StateIniting;
144137

145138
if (DebugManager.flags.OverrideGpuAddressSpace.get() != -1) {
146139
executionEnvironment.getMutableHardwareInfo()->capabilityTable.gpuAddressSpace =
@@ -152,8 +145,8 @@ bool Platform::initialize() {
152145
DEBUG_BREAK_IF(this->platformInfo);
153146
this->platformInfo.reset(new PlatformInfo);
154147

155-
this->clDevices.resize(numDevicesReturned);
156-
for (uint32_t deviceOrdinal = 0; deviceOrdinal < numDevicesReturned; ++deviceOrdinal) {
148+
this->clDevices.resize(numDevices);
149+
for (uint32_t deviceOrdinal = 0; deviceOrdinal < numDevices; ++deviceOrdinal) {
157150
auto pDevice = createRootDevice(deviceOrdinal);
158151
DEBUG_BREAK_IF(!pDevice);
159152
ClDevice *pClDevice = nullptr;
@@ -285,4 +278,8 @@ GmmClientContext *Platform::peekGmmClientContext() const {
285278
return peekGmmHelper()->getClientContext();
286279
}
287280

281+
std::unique_ptr<Platform> (*Platform::createFunc)(ExecutionEnvironment &) = [](ExecutionEnvironment &executionEnvironment) -> std::unique_ptr<Platform> {
282+
return std::make_unique<Platform>(executionEnvironment);
283+
};
284+
288285
} // namespace NEO

runtime/platform/platform.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Platform : public BaseObject<_cl_platform_id> {
4747
void *paramValue,
4848
size_t *paramValueSizeRet);
4949

50-
bool initialize();
50+
bool initialize(size_t numDevices, uint32_t firstRootDeviceIndex);
5151
bool isInitialized();
5252

5353
size_t getNumDevices() const;
@@ -62,6 +62,8 @@ class Platform : public BaseObject<_cl_platform_id> {
6262
GmmHelper *peekGmmHelper() const;
6363
GmmClientContext *peekGmmClientContext() const;
6464

65+
static std::unique_ptr<Platform> (*createFunc)(ExecutionEnvironment &executionEnvironment);
66+
6567
protected:
6668
enum {
6769
StateNone,

unit_tests/api/cl_create_context_from_type_tests.inl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ TEST_F(clCreateContextFromTypeTests, GivenInvalidContextCreationPropertiesWhenCr
7676

7777
TEST_F(clCreateContextFromTypeTests, GivenNonDefaultPlatformInContextCreationPropertiesWhenCreatingContextFromTypeThenSuccessIsReturned) {
7878
auto nonDefaultPlatform = std::make_unique<MockPlatform>();
79-
nonDefaultPlatform->initialize();
79+
size_t numRootDevices;
80+
getDevices(numRootDevices, *nonDefaultPlatform->peekExecutionEnvironment());
81+
nonDefaultPlatform->initialize(numRootDevices, 0);
8082
cl_platform_id nonDefaultPlatformCl = nonDefaultPlatform.get();
8183
cl_context_properties properties[3] = {CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(nonDefaultPlatformCl), 0};
8284
auto clContext = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, nullptr, nullptr, &retVal);
@@ -87,7 +89,9 @@ TEST_F(clCreateContextFromTypeTests, GivenNonDefaultPlatformInContextCreationPro
8789

8890
TEST_F(clCreateContextFromTypeTests, GivenNonDefaultPlatformWithInvalidIcdDispatchInContextCreationPropertiesWhenCreatingContextFromTypeThenInvalidPlatformErrorIsReturned) {
8991
auto nonDefaultPlatform = std::make_unique<MockPlatform>();
90-
nonDefaultPlatform->initialize();
92+
size_t numRootDevices;
93+
getDevices(numRootDevices, *nonDefaultPlatform->peekExecutionEnvironment());
94+
nonDefaultPlatform->initialize(numRootDevices, 0);
9195
cl_platform_id nonDefaultPlatformCl = nonDefaultPlatform.get();
9296
nonDefaultPlatformCl->dispatch.icdDispatch = reinterpret_cast<SDispatchTable *>(nonDefaultPlatform.get());
9397
cl_context_properties properties[3] = {CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(nonDefaultPlatformCl), 0};

unit_tests/api/cl_create_context_tests.inl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ TEST_F(clCreateContextTests, givenInvalidContextCreationPropertiesThenContextCre
9090

9191
TEST_F(clCreateContextTests, GivenNonDefaultPlatformInContextCreationPropertiesWhenCreatingContextThenSuccessIsReturned) {
9292
auto nonDefaultPlatform = std::make_unique<MockPlatform>();
93-
nonDefaultPlatform->initialize();
93+
size_t numRootDevices;
94+
getDevices(numRootDevices, *nonDefaultPlatform->peekExecutionEnvironment());
95+
nonDefaultPlatform->initialize(numRootDevices, 0);
9496
cl_platform_id nonDefaultPlatformCl = nonDefaultPlatform.get();
9597
cl_device_id clDevice = nonDefaultPlatform->getClDevice(0);
9698
cl_context_properties properties[3] = {CL_CONTEXT_PLATFORM, reinterpret_cast<cl_context_properties>(nonDefaultPlatformCl), 0};
@@ -102,7 +104,9 @@ TEST_F(clCreateContextTests, GivenNonDefaultPlatformInContextCreationPropertiesW
102104

103105
TEST_F(clCreateContextFromTypeTests, GivenNonDefaultPlatformWithInvalidIcdDispatchInContextCreationPropertiesWhenCreatingContextThenInvalidPlatformErrorIsReturned) {
104106
auto nonDefaultPlatform = std::make_unique<MockPlatform>();
105-
nonDefaultPlatform->initialize();
107+
size_t numRootDevices;
108+
getDevices(numRootDevices, *nonDefaultPlatform->peekExecutionEnvironment());
109+
nonDefaultPlatform->initialize(numRootDevices, 0);
106110
cl_platform_id nonDefaultPlatformCl = nonDefaultPlatform.get();
107111
nonDefaultPlatformCl->dispatch.icdDispatch = reinterpret_cast<SDispatchTable *>(nonDefaultPlatform.get());
108112
cl_device_id clDevice = nonDefaultPlatform->getClDevice(0);

unit_tests/api/cl_get_device_ids_tests.inl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ TEST_F(clGetDeviceIDsTests, GivenDeviceTypeCpuWhenGettingDeviceIdsThenDeviceNotF
9898
}
9999

100100
TEST(clGetDeviceIDsTest, givenMultipleRootDevicesWhenGetDeviceIdsThenAllRootDevicesAreReturned) {
101+
platformsImpl.clear();
101102
constexpr auto numRootDevices = 3u;
102103
VariableBackup<UltHwConfig> backup(&ultHwConfig);
103104
ultHwConfig.useMockedGetDevicesFunc = false;
@@ -114,6 +115,7 @@ TEST(clGetDeviceIDsTest, givenMultipleRootDevicesWhenGetDeviceIdsThenAllRootDevi
114115
}
115116
}
116117
TEST(clGetDeviceIDsTest, givenMultipleRootDevicesWhenGetDeviceIdsButNumEntriesIsLowerThanNumDevicesThenSubsetOfRootDevicesIsReturned) {
118+
platformsImpl.clear();
117119
constexpr auto numRootDevices = 3u;
118120
VariableBackup<UltHwConfig> backup(&ultHwConfig);
119121
ultHwConfig.useMockedGetDevicesFunc = false;
@@ -144,6 +146,7 @@ TEST(clGetDeviceIDsTest, givenMultipleRootDevicesWhenGetDeviceIdsButNumEntriesIs
144146
}
145147

146148
TEST(clGetDeviceIDsTest, givenMultipleRootDevicesAndLimitedNumberOfReturnedDevicesWhenGetDeviceIdsThenLimitedNumberOfRootDevicesIsReturned) {
149+
platformsImpl.clear();
147150
constexpr auto numRootDevices = 3u;
148151
VariableBackup<UltHwConfig> backup(&ultHwConfig);
149152
ultHwConfig.useMockedGetDevicesFunc = false;
@@ -168,4 +171,24 @@ TEST(clGetDeviceIDsTest, givenMultipleRootDevicesAndLimitedNumberOfReturnedDevic
168171
}
169172
EXPECT_EQ(devices[numDevices], dummyDevice);
170173
}
174+
TEST(clGetDeviceIDsNegativeTests, whenFailToCreateDeviceThenclGetDeviceIDsReturnsNoDeviceError) {
175+
struct FailingPlatform : Platform {
176+
using Platform::Platform;
177+
RootDevice *createRootDevice(uint32_t rootDeviceIndex) const override { return nullptr; }
178+
};
179+
VariableBackup<decltype(Platform::createFunc)> createFuncBackup{&Platform::createFunc};
180+
Platform::createFunc = [](ExecutionEnvironment &executionEnvironment) -> std::unique_ptr<Platform> {
181+
return std::make_unique<FailingPlatform>(executionEnvironment);
182+
};
183+
platformsImpl.clear();
184+
185+
constexpr auto numRootDevices = 3u;
186+
cl_uint numDevices = 0;
187+
cl_uint numEntries = numRootDevices;
188+
cl_device_id devices[numRootDevices];
189+
190+
auto retVal = clGetDeviceIDs(nullptr, CL_DEVICE_TYPE_ALL, numEntries, devices, &numDevices);
191+
EXPECT_EQ(CL_DEVICE_NOT_FOUND, retVal);
192+
EXPECT_EQ(numDevices, 0u);
193+
}
171194
} // namespace ULT

0 commit comments

Comments
 (0)