Skip to content

Commit ab1a76a

Browse files
authored
Merge pull request pocl#1738 from linehill/spirv-ptrcmp
Fix unsupported SPIR-V was generated from OpenCL C
2 parents 15d28c1 + 8ae8492 commit ab1a76a

9 files changed

+228
-99
lines changed

include/pocl.h

+14
Original file line numberDiff line numberDiff line change
@@ -576,4 +576,18 @@ typedef enum
576576
POCL_AUTOLOCALS_TO_ARGS_ONLY_IF_DYNAMIC_LOCALS_PRESENT = 2,
577577
} pocl_autolocals_to_args_strategy;
578578

579+
typedef struct pocl_version_t
580+
{
581+
unsigned major;
582+
unsigned minor;
583+
584+
#ifdef __cplusplus
585+
pocl_version_t () : major (0), minor (0) {}
586+
pocl_version_t (unsigned the_major, unsigned the_minor)
587+
: major (the_major), minor (the_minor)
588+
{
589+
}
590+
#endif
591+
} pocl_version_t;
592+
579593
#endif /* POCL_H */

lib/CL/devices/level0/level0-compilation.cc

+38-5
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,23 @@ Level0Program::~Level0Program() {
167167
}
168168
}
169169

170+
static ze_result_t getTargetSpvVersion(ze_device_handle_t Dev,
171+
pocl_version_t &VersionOut) {
172+
173+
ze_device_module_properties_t ModuleProperties{};
174+
ModuleProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_MODULE_PROPERTIES;
175+
ModuleProperties.pNext = nullptr;
176+
ze_result_t Result = zeDeviceGetModuleProperties(Dev, &ModuleProperties);
177+
if (Result != ZE_RESULT_SUCCESS)
178+
return Result;
179+
180+
VersionOut =
181+
pocl_version_t(ZE_MAJOR_VERSION(ModuleProperties.spirvVersionSupported),
182+
ZE_MINOR_VERSION(ModuleProperties.spirvVersionSupported));
183+
assert(VersionOut.major && "Unexpected SPIR-V version!");
184+
return Result;
185+
}
186+
170187
Level0Program::Level0Program(ze_context_handle_t Ctx, ze_device_handle_t Dev,
171188
bool EnableJIT, bool Optimize, uint32_t NumSpecs,
172189
uint32_t *SpecIDs, const void **SpecValues,
@@ -191,12 +208,18 @@ bool Level0Program::init() {
191208
if (JITCompilation) {
192209
if (ProgramBC.size() <= 20)
193210
return false;
211+
212+
auto TargetVersion = pocl_version_t();
213+
if (getTargetSpvVersion(DeviceH, TargetVersion) != ZE_RESULT_SUCCESS) {
214+
POCL_MSG_ERR("Could not infer target SPIR-V version\n");
215+
return false;
216+
}
217+
194218
char *LinkinSpirvContent = nullptr;
195219
uint64_t LinkinSpirvSize = 0;
196-
ProgramLLVMCtx = pocl_llvm_create_context_for_program(ProgramBC.data(),
197-
ProgramBC.size(),
198-
&LinkinSpirvContent,
199-
&LinkinSpirvSize);
220+
ProgramLLVMCtx = pocl_llvm_create_context_for_program(
221+
ProgramBC.data(), ProgramBC.size(), &LinkinSpirvContent,
222+
&LinkinSpirvSize, TargetVersion);
200223

201224
if (ProgramLLVMCtx == nullptr) {
202225
POCL_MSG_ERR("Null ProgramLLVMCtx\n");
@@ -410,13 +433,23 @@ bool Level0Program::extractKernelSPIRV(std::string &KernelName,
410433
}
411434
}
412435

436+
ze_device_module_properties_t ModuleProperties{};
437+
ModuleProperties.stype = ZE_STRUCTURE_TYPE_DEVICE_MODULE_PROPERTIES;
438+
ModuleProperties.pNext = nullptr;
439+
440+
auto TargetVersion = pocl_version_t();
441+
if (getTargetSpvVersion(DeviceH, TargetVersion) != ZE_RESULT_SUCCESS) {
442+
POCL_MSG_ERR("Could not infer target SPIR-V version\n");
443+
return false;
444+
}
445+
413446
char *SpirvContent = nullptr;
414447
uint64_t SpirvSize = 0;
415448
// to avoid having to hold a lock on the Program, use separate BuildLog
416449
std::string ExtractBuildLog;
417450
int Res = pocl_llvm_extract_kernel_spirv(ProgramLLVMCtx, KernelName.c_str(),
418451
&ExtractBuildLog, &SpirvContent,
419-
&SpirvSize);
452+
&SpirvSize, TargetVersion);
420453

421454
{
422455
std::lock_guard<std::mutex> LockGuard(Mutex);

lib/CL/devices/level0/level0-driver.cc

+5
Original file line numberDiff line numberDiff line change
@@ -2401,6 +2401,11 @@ bool Level0Device::setupModuleProperties(bool &SupportsInt64Atomics,
24012401
if (ModuleProperties.maxArgumentsSize > 256)
24022402
ClDev->max_parameter_size = ModuleProperties.maxArgumentsSize - 64;
24032403
#endif
2404+
2405+
uint32_t SpvVer = ModuleProperties.spirvVersionSupported;
2406+
SupportedSpvVersion =
2407+
pocl_version_t(ZE_MAJOR_VERSION(SpvVer), ZE_MINOR_VERSION(SpvVer));
2408+
24042409
return true;
24052410
}
24062411

lib/CL/devices/level0/level0-driver.hh

+7
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,12 @@ public:
447447
// the batch needs to be split at points where memcpy is required.
448448
bool prefersHostQueues() { return ClDev->type == CL_DEVICE_TYPE_CUSTOM; }
449449

450+
/// Return a SPIR-V version the device supports.
451+
pocl_version_t getSupportedSpvVersion() const {
452+
assert(SupportedSpvVersion.major && "SPIR-V is not supported?");
453+
return SupportedSpvVersion;
454+
}
455+
450456
private:
451457
Level0AllocatorSPtr Alloc;
452458
std::deque<Level0EventPool> EventPools;
@@ -496,6 +502,7 @@ private:
496502
uint32_t MaxMemoryFillPatternSize = 0;
497503
uint32_t GlobalMemOrd = UINT32_MAX;
498504
std::vector<size_t> SupportedSubgroupSizes;
505+
pocl_version_t SupportedSpvVersion = pocl_version_t();
499506

500507
/// initializes kernels used internally by the driver
501508
/// to implement functionality missing in the Level Zero API,

lib/CL/devices/level0/pocl-level0.cc

+20-21
Original file line numberDiff line numberDiff line change
@@ -584,12 +584,12 @@ static int linkWithLLVMLink(cl_program Program, cl_uint DeviceI,
584584
if (Err != CL_SUCCESS)
585585
return Err;
586586

587-
Err = pocl_convert_bitcode_to_spirv(ProgramBcPathTemp,
588-
nullptr, 0,
589-
Program, DeviceI,
590-
1, // useIntelExt
591-
ProgramSpvPathTemp,
592-
nullptr, nullptr);
587+
cl_device_id Dev = Program->devices[DeviceI];
588+
Level0Device *Device = static_cast<Level0Device *>(Dev->data);
589+
Err = pocl_convert_bitcode_to_spirv(
590+
ProgramBcPathTemp, nullptr, 0, Program, DeviceI,
591+
1, // useIntelExt
592+
ProgramSpvPathTemp, nullptr, nullptr, Device->getSupportedSpvVersion());
593593

594594
POCL_RETURN_ERROR_ON((Err != 0), CL_BUILD_PROGRAM_FAILURE,
595595
"llvm-spirv exited with nonzero code\n");
@@ -643,14 +643,12 @@ int pocl_level0_build_source(cl_program Program, cl_uint DeviceI,
643643
if (Err != CL_SUCCESS)
644644
return Err;
645645

646-
Err = pocl_convert_bitcode_to_spirv(nullptr,
647-
(char*)Program->binaries[DeviceI],
648-
Program->binary_sizes[DeviceI],
649-
Program, DeviceI,
650-
1, // useIntelExt
651-
ProgramSpvPathTemp,
652-
&OutputBinary,
653-
&OutputBinarySize);
646+
Err = pocl_convert_bitcode_to_spirv(
647+
nullptr, (char *)Program->binaries[DeviceI],
648+
Program->binary_sizes[DeviceI], Program, DeviceI,
649+
1, // useIntelExt
650+
ProgramSpvPathTemp, &OutputBinary, &OutputBinarySize,
651+
Device->getSupportedSpvVersion());
654652
POCL_RETURN_ERROR_ON((Err != 0), CL_BUILD_PROGRAM_FAILURE,
655653
"llvm-spirv exited with nonzero code\n");
656654

@@ -773,13 +771,14 @@ int pocl_level0_build_binary(cl_program Program, cl_uint DeviceI,
773771
"the binary supplied to level0 driver is "
774772
"not a recognized binary type\n");
775773

776-
Err = pocl_convert_bitcode_to_spirv(ProgramBcPathTemp,
777-
(char *)Program->binaries[DeviceI],
778-
Program->binary_sizes[DeviceI],
779-
Program, DeviceI,
780-
1, // useIntelExt
781-
ProgramSpvPathTemp,
782-
&OutputBinary, &OutputBinarySize);
774+
cl_device_id Dev = Program->devices[DeviceI];
775+
Level0Device *Device = static_cast<Level0Device *>(Dev->data);
776+
Err = pocl_convert_bitcode_to_spirv(
777+
ProgramBcPathTemp, (char *)Program->binaries[DeviceI],
778+
Program->binary_sizes[DeviceI], Program, DeviceI,
779+
1, // useIntelExt
780+
ProgramSpvPathTemp, &OutputBinary, &OutputBinarySize,
781+
Device->getSupportedSpvVersion());
783782
POCL_RETURN_ERROR_ON((Err != 0), CL_BUILD_PROGRAM_FAILURE,
784783
"failed to compile BC -> SPV\n");
785784
Program->program_il = OutputBinary;

lib/CL/pocl_llvm.h

+21-15
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ extern "C" {
144144
void *pocl_llvm_create_context_for_program (char *ProgramBcContent,
145145
size_t ProgramBcSize,
146146
char **LinkinSpirvContent,
147-
uint64_t *LinkinSpirvSize);
147+
uint64_t *LinkinSpirvSize,
148+
pocl_version_t TargetVersion);
148149

149150
/**
150151
* \brief extracts SPIR-V of a single Kernel (plus all functions it uses)
@@ -159,11 +160,12 @@ extern "C" {
159160
*
160161
*/
161162
POCL_EXPORT
162-
int pocl_llvm_extract_kernel_spirv(void* ProgCtx,
163-
const char* KernelName,
164-
void* BuildLogStr,
165-
char **SpirvContent,
166-
uint64_t *SpirvSize);
163+
int pocl_llvm_extract_kernel_spirv (void *ProgCtx,
164+
const char *KernelName,
165+
void *BuildLogStr,
166+
char **SpirvContent,
167+
uint64_t *SpirvSize,
168+
pocl_version_t TargetVersion);
167169

168170
/**
169171
* \brief destroys the instance of hidden class used to extract kernel SPIR-V
@@ -214,6 +216,7 @@ extern "C" {
214216
* nullptr \param [out] SpirvContent pointer where to store the raw output.
215217
* can be nullptr
216218
* \param [out] SpirvSize size of data stored at SpirvContent
219+
* \param [in] TargetVersion The SPIR-V version to emit.
217220
* \returns 0 on success
218221
*
219222
*/
@@ -225,22 +228,25 @@ extern "C" {
225228
int UseIntelExts,
226229
char *TempSpirvPathOut,
227230
char **SpirvContent,
228-
uint64_t *SpirvSize);
231+
uint64_t *SpirvSize,
232+
pocl_version_t TargetVersion);
229233

230234
/**
231235
* \brief converts LLVM IR with "spir64-unknown-unknown" triple to SPIR-V
232236
*
233237
* The same as pocl_convert_bitcode_to_spirv, but takes a std::string*
234238
* cast to void* as buildLog argument
235239
*/
236-
POCL_EXPORT int pocl_convert_bitcode_to_spirv2 (char *TempBitcodePath,
237-
const char *Bitcode,
238-
uint64_t BitcodeSize,
239-
void *BuildLog,
240-
int UseIntelExts,
241-
char *TempSpirvPathOut,
242-
char **SpirvContent,
243-
uint64_t *SpirvSize);
240+
POCL_EXPORT int
241+
pocl_convert_bitcode_to_spirv2 (char *TempBitcodePath,
242+
const char *Bitcode,
243+
uint64_t BitcodeSize,
244+
void *BuildLog,
245+
int UseIntelExts,
246+
char *TempSpirvPathOut,
247+
char **SpirvContent,
248+
uint64_t *SpirvSize,
249+
pocl_version_t TargetVersion);
244250

245251
/**
246252
* \brief converts SPIR-V to LLVM IR with "spir64-unknown-unknown" triple

0 commit comments

Comments
 (0)