1 /*
2 * Copyright (C) 2018-2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8 #include "platform.h"
9
10 #include "shared/source/built_ins/sip.h"
11 #include "shared/source/command_stream/command_stream_receiver.h"
12 #include "shared/source/compiler_interface/compiler_interface.h"
13 #include "shared/source/compiler_interface/oclc_extensions.h"
14 #include "shared/source/debug_settings/debug_settings_manager.h"
15 #include "shared/source/device/root_device.h"
16 #include "shared/source/execution_environment/execution_environment.h"
17 #include "shared/source/execution_environment/root_device_environment.h"
18 #include "shared/source/gmm_helper/gmm_helper.h"
19 #include "shared/source/helpers/debug_helpers.h"
20 #include "shared/source/helpers/get_info.h"
21 #include "shared/source/helpers/hw_helper.h"
22 #include "shared/source/helpers/string.h"
23 #include "shared/source/os_interface/device_factory.h"
24 #include "shared/source/os_interface/os_interface.h"
25 #include "shared/source/source_level_debugger/source_level_debugger.h"
26
27 #include "opencl/source/api/api.h"
28 #include "opencl/source/cl_device/cl_device.h"
29 #include "opencl/source/gtpin/gtpin_notify.h"
30 #include "opencl/source/helpers/get_info_status_mapper.h"
31 #include "opencl/source/sharings/sharing_factory.h"
32
33 #include "CL/cl_ext.h"
34
35 #include <algorithm>
36 #include <map>
37 namespace NEO {
38
39 std::vector<std::unique_ptr<Platform>> *platformsImpl = nullptr;
40
Platform(ExecutionEnvironment & executionEnvironmentIn)41 Platform::Platform(ExecutionEnvironment &executionEnvironmentIn) : executionEnvironment(executionEnvironmentIn) {
42 clDevices.reserve(4);
43 executionEnvironment.incRefInternal();
44 }
45
~Platform()46 Platform::~Platform() {
47 for (auto clDevice : this->clDevices) {
48 clDevice->decRefInternal();
49 }
50
51 gtpinNotifyPlatformShutdown();
52 executionEnvironment.decRefInternal();
53 }
54
getInfo(cl_platform_info paramName,size_t paramValueSize,void * paramValue,size_t * paramValueSizeRet)55 cl_int Platform::getInfo(cl_platform_info paramName,
56 size_t paramValueSize,
57 void *paramValue,
58 size_t *paramValueSizeRet) {
59 auto retVal = CL_INVALID_VALUE;
60 const std::string *param = nullptr;
61 size_t paramSize = GetInfo::invalidSourceSize;
62 auto getInfoStatus = GetInfoStatus::INVALID_VALUE;
63
64 switch (paramName) {
65 case CL_PLATFORM_HOST_TIMER_RESOLUTION: {
66 auto pVal = static_cast<uint64_t>(this->clDevices[0]->getPlatformHostTimerResolution());
67 paramSize = sizeof(uint64_t);
68 getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, &pVal, paramSize);
69 break;
70 }
71 case CL_PLATFORM_NUMERIC_VERSION: {
72 auto pVal = platformInfo->numericVersion;
73 paramSize = sizeof(pVal);
74 getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, &pVal, paramSize);
75 break;
76 }
77 case CL_PLATFORM_EXTENSIONS_WITH_VERSION: {
78 std::call_once(initializeExtensionsWithVersionOnce, [this]() {
79 this->clDevices[0]->getDeviceInfo(CL_DEVICE_EXTENSIONS_WITH_VERSION, 0, nullptr, nullptr);
80 this->platformInfo->extensionsWithVersion = this->clDevices[0]->getDeviceInfo().extensionsWithVersion;
81 });
82
83 auto pVal = platformInfo->extensionsWithVersion.data();
84 paramSize = platformInfo->extensionsWithVersion.size() * sizeof(cl_name_version);
85 getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, pVal, paramSize);
86 break;
87 }
88 case CL_PLATFORM_PROFILE:
89 param = &platformInfo->profile;
90 break;
91 case CL_PLATFORM_VERSION:
92 param = &platformInfo->version;
93 break;
94 case CL_PLATFORM_NAME:
95 param = &platformInfo->name;
96 break;
97 case CL_PLATFORM_VENDOR:
98 param = &platformInfo->vendor;
99 break;
100 case CL_PLATFORM_EXTENSIONS:
101 param = &platformInfo->extensions;
102 break;
103 case CL_PLATFORM_ICD_SUFFIX_KHR:
104 param = &platformInfo->icdSuffixKhr;
105 break;
106 default:
107 break;
108 }
109
110 // Case for string parameters
111 if (param) {
112 paramSize = param->length() + 1;
113 getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, param->c_str(), paramSize);
114 }
115
116 retVal = changeGetInfoStatusToCLResultType(getInfoStatus);
117 GetInfo::setParamValueReturnSize(paramValueSizeRet, paramSize, getInfoStatus);
118
119 return retVal;
120 }
121
initialize(std::vector<std::unique_ptr<Device>> devices)122 bool Platform::initialize(std::vector<std::unique_ptr<Device>> devices) {
123
124 TakeOwnershipWrapper<Platform> platformOwnership(*this);
125 if (devices.empty()) {
126 return false;
127 }
128 if (state == StateInited) {
129 return true;
130 }
131
132 state = StateIniting;
133
134 for (auto &inputDevice : devices) {
135 ClDevice *pClDevice = nullptr;
136 auto pDevice = inputDevice.release();
137 UNRECOVERABLE_IF(!pDevice);
138 pClDevice = new ClDevice{*pDevice, this};
139 this->clDevices.push_back(pClDevice);
140
141 if (pClDevice->getPreemptionMode() == PreemptionMode::MidThread || pClDevice->isDebuggerActive()) {
142 bool ret = SipKernel::initSipKernel(SipKernel::getSipKernelType(*pDevice), *pDevice);
143 UNRECOVERABLE_IF(!ret);
144 }
145 }
146
147 DEBUG_BREAK_IF(this->platformInfo);
148 this->platformInfo.reset(new PlatformInfo);
149
150 this->platformInfo->extensions = this->clDevices[0]->getDeviceInfo().deviceExtensions;
151
152 switch (this->clDevices[0]->getEnabledClVersion()) {
153 case 30:
154 this->platformInfo->version = "OpenCL 3.0 ";
155 this->platformInfo->numericVersion = CL_MAKE_VERSION(3, 0, 0);
156 break;
157 case 21:
158 this->platformInfo->version = "OpenCL 2.1 ";
159 this->platformInfo->numericVersion = CL_MAKE_VERSION(2, 1, 0);
160 break;
161 default:
162 this->platformInfo->version = "OpenCL 1.2 ";
163 this->platformInfo->numericVersion = CL_MAKE_VERSION(1, 2, 0);
164 break;
165 }
166
167 this->fillGlobalDispatchTable();
168 DEBUG_BREAK_IF(DebugManager.flags.CreateMultipleSubDevices.get() > 1 && !this->clDevices[0]->getDefaultEngine().commandStreamReceiver->peekTimestampPacketWriteEnabled());
169 state = StateInited;
170 return true;
171 }
172
fillGlobalDispatchTable()173 void Platform::fillGlobalDispatchTable() {
174 sharingFactory.fillGlobalDispatchTable();
175 }
176
isInitialized()177 bool Platform::isInitialized() {
178 TakeOwnershipWrapper<Platform> platformOwnership(*this);
179 bool ret = (this->state == StateInited);
180 return ret;
181 }
182
getClDevice(size_t deviceOrdinal)183 ClDevice *Platform::getClDevice(size_t deviceOrdinal) {
184 TakeOwnershipWrapper<Platform> platformOwnership(*this);
185
186 if (this->state != StateInited || deviceOrdinal >= clDevices.size()) {
187 return nullptr;
188 }
189
190 auto pClDevice = clDevices[deviceOrdinal];
191 DEBUG_BREAK_IF(pClDevice == nullptr);
192
193 return pClDevice;
194 }
195
getNumDevices() const196 size_t Platform::getNumDevices() const {
197 TakeOwnershipWrapper<const Platform> platformOwnership(*this);
198
199 if (this->state != StateInited) {
200 return 0;
201 }
202
203 return clDevices.size();
204 }
205
getClDevices()206 ClDevice **Platform::getClDevices() {
207 TakeOwnershipWrapper<Platform> platformOwnership(*this);
208
209 if (this->state != StateInited) {
210 return nullptr;
211 }
212
213 return clDevices.data();
214 }
215
getPlatformInfo() const216 const PlatformInfo &Platform::getPlatformInfo() const {
217 DEBUG_BREAK_IF(!platformInfo);
218 return *platformInfo;
219 }
220
__anond14040e80202(ExecutionEnvironment &executionEnvironment) 221 std::unique_ptr<Platform> (*Platform::createFunc)(ExecutionEnvironment &) = [](ExecutionEnvironment &executionEnvironment) -> std::unique_ptr<Platform> {
222 return std::make_unique<Platform>(executionEnvironment);
223 };
224
groupDevices(DeviceVector devices)225 std::vector<DeviceVector> Platform::groupDevices(DeviceVector devices) {
226 std::map<PRODUCT_FAMILY, size_t> platformsMap;
227 std::vector<DeviceVector> outDevices;
228 for (auto &device : devices) {
229 auto productFamily = device->getHardwareInfo().platform.eProductFamily;
230 auto result = platformsMap.find(productFamily);
231 if (result == platformsMap.end()) {
232 platformsMap.insert({productFamily, platformsMap.size()});
233 outDevices.push_back(DeviceVector{});
234 }
235 auto platformId = platformsMap[productFamily];
236 outDevices[platformId].push_back(std::move(device));
237 }
238 std::sort(outDevices.begin(), outDevices.end(), [](DeviceVector &lhs, DeviceVector &rhs) -> bool {
239 return lhs[0]->getHardwareInfo().platform.eProductFamily > rhs[0]->getHardwareInfo().platform.eProductFamily;
240 });
241 return outDevices;
242 }
243
244 } // namespace NEO
245