1 /*
2 * Copyright (C) 2018-2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 */
7
8 #include "shared/source/helpers/get_info.h"
9
10 #include "shared/source/device/device.h"
11 #include "shared/source/program/kernel_info.h"
12
13 #include "opencl/source/cl_device/cl_device.h"
14 #include "opencl/source/context/context.h"
15 #include "opencl/source/helpers/base_object.h"
16 #include "opencl/source/helpers/cl_validators.h"
17 #include "opencl/source/helpers/get_info_status_mapper.h"
18
19 #include "program.h"
20
21 namespace NEO {
22
getInfo(cl_program_info paramName,size_t paramValueSize,void * paramValue,size_t * paramValueSizeRet)23 cl_int Program::getInfo(cl_program_info paramName, size_t paramValueSize,
24 void *paramValue, size_t *paramValueSizeRet) {
25 cl_int retVal = CL_SUCCESS;
26 const void *pSrc = nullptr;
27 size_t srcSize = GetInfo::invalidSourceSize;
28 size_t retSize = 0;
29 std::string kernelNamesString;
30 cl_uint refCount = 0;
31 size_t numKernels;
32 cl_context clContext = context;
33 cl_uint clFalse = CL_FALSE;
34 std::vector<cl_device_id> devicesToExpose;
35 StackVec<size_t, 1> binarySizes;
36 uint32_t numDevices = static_cast<uint32_t>(clDevices.size());
37
38 switch (paramName) {
39 case CL_PROGRAM_CONTEXT:
40 pSrc = &clContext;
41 retSize = srcSize = sizeof(clContext);
42 break;
43
44 case CL_PROGRAM_BINARIES: {
45 auto requiredSize = clDevices.size() * sizeof(const unsigned char **);
46 if (!paramValue) {
47 retSize = requiredSize;
48 srcSize = 0u;
49 break;
50 }
51 if (paramValueSize < requiredSize) {
52 retVal = CL_INVALID_VALUE;
53 break;
54 }
55 auto outputBinaries = reinterpret_cast<unsigned char **>(paramValue);
56 for (auto i = 0u; i < clDevices.size(); i++) {
57 if (outputBinaries[i] == nullptr) {
58 continue;
59 }
60 auto rootDeviceIndex = clDevices[i]->getRootDeviceIndex();
61 auto binarySize = buildInfos[rootDeviceIndex].packedDeviceBinarySize;
62 memcpy_s(outputBinaries[i], binarySize, buildInfos[rootDeviceIndex].packedDeviceBinary.get(), binarySize);
63 }
64 GetInfo::setParamValueReturnSize(paramValueSizeRet, requiredSize, GetInfoStatus::SUCCESS);
65 return CL_SUCCESS;
66 } break;
67
68 case CL_PROGRAM_BINARY_SIZES:
69 for (auto i = 0u; i < clDevices.size(); i++) {
70 auto rootDeviceIndex = clDevices[i]->getRootDeviceIndex();
71 packDeviceBinary(*clDevices[i]);
72 binarySizes.push_back(buildInfos[rootDeviceIndex].packedDeviceBinarySize);
73 }
74
75 pSrc = binarySizes.data();
76 retSize = srcSize = binarySizes.size() * sizeof(cl_device_id);
77 break;
78
79 case CL_PROGRAM_KERNEL_NAMES:
80 kernelNamesString = concatenateKernelNames(buildInfos[clDevices[0]->getRootDeviceIndex()].kernelInfoArray);
81 pSrc = kernelNamesString.c_str();
82 retSize = srcSize = kernelNamesString.length() + 1;
83
84 if (!isBuilt()) {
85 retVal = CL_INVALID_PROGRAM_EXECUTABLE;
86 }
87 break;
88
89 case CL_PROGRAM_NUM_KERNELS:
90 numKernels = getNumKernels();
91 pSrc = &numKernels;
92 retSize = srcSize = sizeof(numKernels);
93
94 if (!isBuilt()) {
95 retVal = CL_INVALID_PROGRAM_EXECUTABLE;
96 }
97 break;
98
99 case CL_PROGRAM_NUM_DEVICES:
100 pSrc = &numDevices;
101 retSize = srcSize = sizeof(cl_uint);
102 break;
103
104 case CL_PROGRAM_DEVICES:
105 clDevices.toDeviceIDs(devicesToExpose);
106 pSrc = devicesToExpose.data();
107 retSize = srcSize = devicesToExpose.size() * sizeof(cl_device_id);
108 break;
109
110 case CL_PROGRAM_REFERENCE_COUNT:
111 refCount = static_cast<cl_uint>(this->getReference());
112 retSize = srcSize = sizeof(refCount);
113 pSrc = &refCount;
114 break;
115
116 case CL_PROGRAM_SOURCE:
117 if (createdFrom == CreatedFrom::SOURCE) {
118 pSrc = sourceCode.c_str();
119 retSize = srcSize = strlen(sourceCode.c_str()) + 1;
120 } else {
121 if (paramValueSizeRet) {
122 *paramValueSizeRet = 0;
123 }
124 return CL_SUCCESS;
125 }
126 break;
127
128 case CL_PROGRAM_IL:
129 if (createdFrom != CreatedFrom::IL) {
130 if (paramValueSizeRet) {
131 *paramValueSizeRet = 0;
132 }
133 return CL_SUCCESS;
134 }
135 pSrc = irBinary.get();
136 retSize = srcSize = irBinarySize;
137 break;
138
139 case CL_PROGRAM_DEBUG_INFO_SIZES_INTEL:
140 retSize = srcSize = sizeof(debugDataSize);
141 pSrc = &debugDataSize;
142 break;
143
144 case CL_PROGRAM_DEBUG_INFO_INTEL:
145 pSrc = debugData.get();
146 retSize = numDevices * sizeof(void **);
147 srcSize = debugDataSize;
148 if (paramValue != nullptr) {
149 if (paramValueSize < retSize) {
150 retVal = CL_INVALID_VALUE;
151 break;
152 }
153 paramValueSize = srcSize;
154 paramValue = *(void **)paramValue;
155 }
156 break;
157
158 case CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT:
159 case CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT:
160 retSize = srcSize = sizeof(clFalse);
161 pSrc = &clFalse;
162 break;
163
164 default:
165 retVal = CL_INVALID_VALUE;
166 break;
167 }
168
169 auto getInfoStatus = GetInfoStatus::INVALID_VALUE;
170 if (retVal == CL_SUCCESS) {
171 getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, pSrc, srcSize);
172 retVal = changeGetInfoStatusToCLResultType(getInfoStatus);
173 }
174 GetInfo::setParamValueReturnSize(paramValueSizeRet, retSize, getInfoStatus);
175 return retVal;
176 }
177
getBuildInfo(cl_device_id device,cl_program_build_info paramName,size_t paramValueSize,void * paramValue,size_t * paramValueSizeRet) const178 cl_int Program::getBuildInfo(cl_device_id device, cl_program_build_info paramName,
179 size_t paramValueSize, void *paramValue, size_t *paramValueSizeRet) const {
180 cl_int retVal = CL_SUCCESS;
181 const void *pSrc = nullptr;
182 size_t srcSize = GetInfo::invalidSourceSize;
183 size_t retSize = 0;
184
185 auto pClDev = castToObject<ClDevice>(device);
186 auto rootDeviceIndex = pClDev->getRootDeviceIndex();
187
188 switch (paramName) {
189 case CL_PROGRAM_BUILD_STATUS:
190 srcSize = retSize = sizeof(cl_build_status);
191 pSrc = &deviceBuildInfos.at(pClDev).buildStatus;
192 break;
193
194 case CL_PROGRAM_BUILD_OPTIONS:
195 srcSize = retSize = strlen(options.c_str()) + 1;
196 pSrc = options.c_str();
197 break;
198
199 case CL_PROGRAM_BUILD_LOG: {
200 const char *pBuildLog = getBuildLog(pClDev->getRootDeviceIndex());
201
202 pSrc = pBuildLog;
203 srcSize = retSize = strlen(pBuildLog) + 1;
204 } break;
205
206 case CL_PROGRAM_BINARY_TYPE:
207 srcSize = retSize = sizeof(cl_program_binary_type);
208 pSrc = &deviceBuildInfos.at(pClDev).programBinaryType;
209 break;
210
211 case CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE:
212 pSrc = &buildInfos[rootDeviceIndex].globalVarTotalSize;
213 retSize = srcSize = sizeof(size_t);
214 break;
215
216 default:
217 retVal = CL_INVALID_VALUE;
218 break;
219 }
220
221 auto getInfoStatus = GetInfoStatus::INVALID_VALUE;
222 if (retVal == CL_SUCCESS) {
223 getInfoStatus = GetInfo::getInfo(paramValue, paramValueSize, pSrc, srcSize);
224 retVal = changeGetInfoStatusToCLResultType(getInfoStatus);
225 }
226 GetInfo::setParamValueReturnSize(paramValueSizeRet, retSize, getInfoStatus);
227
228 return retVal;
229 }
230 } // namespace NEO
231