Skip to content

Commit 8a2b204

Browse files
committed
Function/Global pointers API
Change-Id: I226b0cf75b6f3c72deb7418df647aa5781be09d6 Signed-off-by: Chodor, Jaroslaw <jaroslaw.chodor@intel.com>
1 parent 552a126 commit 8a2b204

File tree

5 files changed

+203
-0
lines changed

5 files changed

+203
-0
lines changed

runtime/api/api.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3791,6 +3791,8 @@ void *CL_API_CALL clGetExtensionFunctionAddress(const char *funcName) {
37913791
RETURN_FUNC_PTR_IF_EXIST(clEnqueueMemcpyINTEL);
37923792
RETURN_FUNC_PTR_IF_EXIST(clEnqueueMigrateMemINTEL);
37933793
RETURN_FUNC_PTR_IF_EXIST(clEnqueueMemAdviseINTEL);
3794+
RETURN_FUNC_PTR_IF_EXIST(clGetDeviceFunctionPointerINTEL);
3795+
RETURN_FUNC_PTR_IF_EXIST(clGetDeviceGlobalVariablePointerINTEL);
37943796

37953797
void *ret = sharingFactory.getExtensionFunctionAddress(funcName);
37963798
if (ret != nullptr) {
@@ -4893,6 +4895,68 @@ cl_int CL_API_CALL clAddCommentINTEL(cl_platform_id platform, const char *commen
48934895
return retVal;
48944896
}
48954897

4898+
cl_int CL_API_CALL clGetDeviceGlobalVariablePointerINTEL(
4899+
cl_device_id device,
4900+
cl_program program,
4901+
const char *globalVariableName,
4902+
size_t *globalVariableSizeRet,
4903+
void **globalVariablePointerRet) {
4904+
cl_int retVal = CL_SUCCESS;
4905+
API_ENTER(&retVal);
4906+
DBG_LOG_INPUTS("device", device, "program", program,
4907+
"globalVariableName", globalVariableName,
4908+
"globalVariablePointerRet", globalVariablePointerRet);
4909+
retVal = validateObjects(device, program);
4910+
if (globalVariablePointerRet == nullptr) {
4911+
retVal = CL_INVALID_ARG_VALUE;
4912+
}
4913+
4914+
if (CL_SUCCESS == retVal) {
4915+
Program *pProgram = (Program *)(program);
4916+
const auto &symbols = pProgram->getSymbols();
4917+
auto symbolIt = symbols.find(globalVariableName);
4918+
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.type == NEO::SymbolInfo::Function)) {
4919+
retVal = CL_INVALID_ARG_VALUE;
4920+
} else {
4921+
if (globalVariableSizeRet != nullptr) {
4922+
*globalVariableSizeRet = symbolIt->second.symbol.size;
4923+
}
4924+
*globalVariablePointerRet = reinterpret_cast<void *>(symbolIt->second.gpuAddress);
4925+
}
4926+
}
4927+
4928+
return retVal;
4929+
}
4930+
4931+
cl_int CL_API_CALL clGetDeviceFunctionPointerINTEL(
4932+
cl_device_id device,
4933+
cl_program program,
4934+
const char *functionName,
4935+
cl_ulong *functionPointerRet) {
4936+
cl_int retVal = CL_SUCCESS;
4937+
API_ENTER(&retVal);
4938+
DBG_LOG_INPUTS("device", device, "program", program,
4939+
"functionName", functionName,
4940+
"functionPointerRet", functionPointerRet);
4941+
retVal = validateObjects(device, program);
4942+
if ((CL_SUCCESS == retVal) && (functionPointerRet == nullptr)) {
4943+
retVal = CL_INVALID_ARG_VALUE;
4944+
}
4945+
4946+
if (CL_SUCCESS == retVal) {
4947+
Program *pProgram = (Program *)(program);
4948+
const auto &symbols = pProgram->getSymbols();
4949+
auto symbolIt = symbols.find(functionName);
4950+
if ((symbolIt == symbols.end()) || (symbolIt->second.symbol.type != NEO::SymbolInfo::Function)) {
4951+
retVal = CL_INVALID_ARG_VALUE;
4952+
} else {
4953+
*functionPointerRet = static_cast<cl_ulong>(symbolIt->second.gpuAddress);
4954+
}
4955+
}
4956+
4957+
return retVal;
4958+
}
4959+
48964960
cl_int CL_API_CALL clSetProgramSpecializationConstant(cl_program program, cl_uint specId, size_t specSize, const void *specValue) {
48974961
cl_int retVal = CL_SUCCESS;
48984962
API_ENTER(&retVal);

runtime/api/api.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,19 @@ cl_int clEnqueueMemAdviseINTEL(
10021002
cl_event *event);
10031003
}
10041004

1005+
cl_int CL_API_CALL clGetDeviceFunctionPointerINTEL(
1006+
cl_device_id device,
1007+
cl_program program,
1008+
const char *functionName,
1009+
cl_ulong *functionPointerRet);
1010+
1011+
cl_int CL_API_CALL clGetDeviceGlobalVariablePointerINTEL(
1012+
cl_device_id device,
1013+
cl_program program,
1014+
const char *globalVariableName,
1015+
size_t *globalVariableSizeRet,
1016+
void **globalVariablePointerRet);
1017+
10051018
// OpenCL 2.2
10061019

10071020
cl_int CL_API_CALL clSetProgramSpecializationConstant(

unit_tests/api/api_tests_wrapper1.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@
3535
#include "unit_tests/api/cl_enqueue_map_image_tests.inl"
3636
#include "unit_tests/api/cl_enqueue_marker_tests.inl"
3737
#include "unit_tests/api/cl_enqueue_marker_with_wait_list_tests.inl"
38+
#include "unit_tests/api/cl_function_pointers_tests.inl"
3839
#include "unit_tests/api/cl_unified_shared_memory_tests.inl"
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright (C) 2017-2019 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "unit_tests/mocks/mock_program.h"
9+
10+
#include "cl_api_tests.h"
11+
12+
using namespace NEO;
13+
14+
using clGetDeviceGlobalVariablePointer = api_tests;
15+
using clGetDeviceFunctionPointer = api_tests;
16+
17+
TEST_F(clGetDeviceGlobalVariablePointer, GivenNullMandatoryArgumentsThenReturnInvalidArgError) {
18+
this->pProgram->symbols["A"].gpuAddress = 7U;
19+
this->pProgram->symbols["A"].symbol.size = 64U;
20+
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::GlobalVariable;
21+
22+
void *globalRet = 0;
23+
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, &globalRet);
24+
EXPECT_EQ(CL_SUCCESS, ret);
25+
EXPECT_EQ(7U, reinterpret_cast<uintptr_t>(globalRet));
26+
27+
ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, nullptr);
28+
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
29+
30+
ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), nullptr, "A", nullptr, &globalRet);
31+
EXPECT_EQ(CL_INVALID_PROGRAM, ret);
32+
33+
ret = clGetDeviceGlobalVariablePointerINTEL(nullptr, this->pProgram, "A", nullptr, &globalRet);
34+
EXPECT_EQ(CL_INVALID_DEVICE, ret);
35+
}
36+
37+
TEST_F(clGetDeviceGlobalVariablePointer, GivenValidSymbolNameThenReturnProperAddressAndSize) {
38+
this->pProgram->symbols["A"].gpuAddress = 7U;
39+
this->pProgram->symbols["A"].symbol.size = 64U;
40+
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::GlobalVariable;
41+
42+
void *globalRet = 0;
43+
size_t sizeRet = 0;
44+
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &sizeRet, &globalRet);
45+
EXPECT_EQ(CL_SUCCESS, ret);
46+
EXPECT_EQ(7U, reinterpret_cast<uintptr_t>(globalRet));
47+
EXPECT_EQ(64U, sizeRet);
48+
}
49+
50+
TEST_F(clGetDeviceGlobalVariablePointer, GivenFunctionSymbolNameThenReturnInvalidArgError) {
51+
this->pProgram->symbols["A"].gpuAddress = 7U;
52+
this->pProgram->symbols["A"].symbol.size = 64U;
53+
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::Function;
54+
55+
void *globalRet = 0;
56+
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, &globalRet);
57+
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
58+
}
59+
60+
TEST_F(clGetDeviceGlobalVariablePointer, GivenUnknownSymbolNameThenReturnInvalidArgError) {
61+
void *globalRet = 0;
62+
auto ret = clGetDeviceGlobalVariablePointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr, &globalRet);
63+
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
64+
}
65+
66+
TEST_F(clGetDeviceFunctionPointer, GivenNullMandatoryArgumentsThenReturnInvalidArgError) {
67+
this->pProgram->symbols["A"].gpuAddress = 7U;
68+
this->pProgram->symbols["A"].symbol.size = 64U;
69+
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::Function;
70+
71+
cl_ulong fptrRet = 0;
72+
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
73+
EXPECT_EQ(CL_SUCCESS, ret);
74+
EXPECT_EQ(7U, fptrRet);
75+
76+
ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", nullptr);
77+
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
78+
79+
ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), nullptr, "A", &fptrRet);
80+
EXPECT_EQ(CL_INVALID_PROGRAM, ret);
81+
82+
ret = clGetDeviceFunctionPointerINTEL(nullptr, this->pProgram, "A", &fptrRet);
83+
EXPECT_EQ(CL_INVALID_DEVICE, ret);
84+
}
85+
86+
TEST_F(clGetDeviceFunctionPointer, GivenValidSymbolNameThenReturnProperAddress) {
87+
this->pProgram->symbols["A"].gpuAddress = 7U;
88+
this->pProgram->symbols["A"].symbol.size = 64U;
89+
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::Function;
90+
91+
cl_ulong fptrRet = 0;
92+
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
93+
EXPECT_EQ(CL_SUCCESS, ret);
94+
EXPECT_EQ(7U, fptrRet);
95+
}
96+
97+
TEST_F(clGetDeviceFunctionPointer, GivenGlobalSymbolNameThenReturnInvalidArgError) {
98+
this->pProgram->symbols["A"].gpuAddress = 7U;
99+
this->pProgram->symbols["A"].symbol.size = 64U;
100+
this->pProgram->symbols["A"].symbol.type = NEO::SymbolInfo::GlobalVariable;
101+
this->pProgram->symbols["B"].gpuAddress = 7U;
102+
this->pProgram->symbols["B"].symbol.size = 64U;
103+
this->pProgram->symbols["B"].symbol.type = NEO::SymbolInfo::GlobalConstant;
104+
105+
cl_ulong fptrRet = 0;
106+
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
107+
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
108+
ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "B", &fptrRet);
109+
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
110+
}
111+
TEST_F(clGetDeviceFunctionPointer, GivenUnknownSymbolNameThenReturnInvalidArgError) {
112+
cl_ulong fptrRet = 0;
113+
auto ret = clGetDeviceFunctionPointerINTEL(this->pContext->getDevice(0), this->pProgram, "A", &fptrRet);
114+
EXPECT_EQ(CL_INVALID_ARG_VALUE, ret);
115+
}

unit_tests/api/cl_get_extension_function_address_tests.inl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,14 @@ TEST_F(clGetExtensionFunctionAddressTests, GivenClEnqueueMemAdviseINTELWhenGetti
147147
auto retVal = clGetExtensionFunctionAddress("clEnqueueMemAdviseINTEL");
148148
EXPECT_EQ(retVal, reinterpret_cast<void *>(clEnqueueMemAdviseINTEL));
149149
}
150+
151+
TEST_F(clGetExtensionFunctionAddressTests, GivenClGetDeviceGlobalVariablePointerINTELWhenGettingExtensionFunctionThenCorrectAddressIsReturned) {
152+
auto retVal = clGetExtensionFunctionAddress("clGetDeviceGlobalVariablePointerINTEL");
153+
EXPECT_EQ(retVal, reinterpret_cast<void *>(clGetDeviceGlobalVariablePointerINTEL));
154+
}
155+
156+
TEST_F(clGetExtensionFunctionAddressTests, GivenClGetDeviceFunctionPointerINTELWhenGettingExtensionFunctionThenCorrectAddressIsReturned) {
157+
auto retVal = clGetExtensionFunctionAddress("clGetDeviceFunctionPointerINTEL");
158+
EXPECT_EQ(retVal, reinterpret_cast<void *>(clGetDeviceFunctionPointerINTEL));
159+
}
150160
} // namespace ULT

0 commit comments

Comments
 (0)