@@ -59,13 +59,16 @@ pi_result OCL(piDevicesGet)(pi_platform platform,
59
59
return cast<pi_result>(result);
60
60
}
61
61
62
- pi_result OCL (piextDeviceSelectBinary)(
63
- pi_device device, // TODO: does this need to be context?
64
- pi_device_binary * images,
65
- pi_uint32 num_images,
66
- pi_device_binary * selected_image) {
67
-
68
- // TODO dummy implementation.
62
+ pi_result OCL (piextDeviceSelectBinary)(pi_device device,
63
+ pi_device_binary *images,
64
+ pi_uint32 num_images,
65
+ pi_device_binary *selected_image) {
66
+
67
+ // TODO: this is a bare-bones implementation for choosing a device image
68
+ // that would be compatible with the targeted device. An AOT-compiled
69
+ // image is preferred over SPIRV for known devices (i.e. Intel devices)
70
+ // The implementation makes no effort to differentiate between multiple images
71
+ // for the given device, and simply picks the first one compatible
69
72
// Real implementaion will use the same mechanism OpenCL ICD dispatcher
70
73
// uses. Somthing like:
71
74
// PI_VALIDATE_HANDLE_RETURN_HANDLE(ctx, PI_INVALID_CONTEXT);
@@ -74,8 +77,56 @@ pi_result OCL(piextDeviceSelectBinary)(
74
77
// where context->dispatch is set to the dispatch table provided by PI
75
78
// plugin for platform/device the ctx was created for.
76
79
77
- *selected_image = num_images > 0 ? images[0 ] : nullptr ;
78
- return PI_SUCCESS;
80
+ // Choose the binary target for the provided device
81
+ const char *image_target = nullptr ;
82
+ // Get the type of the device
83
+ cl_device_type device_type;
84
+ cl_int ret_err = clGetDeviceInfo (cast<cl_device_id >(device), CL_DEVICE_TYPE,
85
+ sizeof (cl_device_type), &device_type, nullptr );
86
+ if (ret_err != CL_SUCCESS) {
87
+ *selected_image = nullptr ;
88
+ return cast<pi_result>(ret_err);
89
+ }
90
+
91
+ switch (device_type) {
92
+ // TODO: Factor out vendor specifics into a separate source
93
+ // E.g. sycl/source/detail/vendor/intel/detail/pi_opencl.cpp?
94
+
95
+ // We'll attempt to find an image that was AOT-compiled
96
+ // from a SPIR-V image into an image specific for:
97
+
98
+ case CL_DEVICE_TYPE_CPU: // OpenCL 64-bit CPU
99
+ image_target = PI_DEVICE_BINARY_TARGET_SPIRV64_X86_64;
100
+ break ;
101
+ case CL_DEVICE_TYPE_GPU: // OpenCL 64-bit GEN GPU
102
+ image_target = PI_DEVICE_BINARY_TARGET_SPIRV64_GEN;
103
+ break ;
104
+ case CL_DEVICE_TYPE_ACCELERATOR: // OpenCL 64-bit FPGA
105
+ image_target = PI_DEVICE_BINARY_TARGET_SPIRV64_FPGA;
106
+ break ;
107
+ default :
108
+ // Otherwise, we'll attempt to find and JIT-compile
109
+ // a device-independent SPIR-V image
110
+ image_target = PI_DEVICE_BINARY_TARGET_SPIRV64;
111
+ break ;
112
+ }
113
+
114
+ // Find the appropriate device image, fallback to spirv if not found
115
+ pi_device_binary fallback = nullptr ;
116
+ for (size_t i = 0 ; i < num_images; ++i) {
117
+ if (strcmp (images[i]->DeviceTargetSpec , image_target) == 0 ) {
118
+ *selected_image = images[i];
119
+ return PI_SUCCESS;
120
+ }
121
+ if (strcmp (images[i]->DeviceTargetSpec , PI_DEVICE_BINARY_TARGET_SPIRV64) ==
122
+ 0 )
123
+ fallback = images[i];
124
+ }
125
+ // Points to a spirv image, if such indeed was found
126
+ if ((*selected_image = fallback))
127
+ return PI_SUCCESS;
128
+ // No image can be loaded for the given device
129
+ return PI_INVALID_BINARY;
79
130
}
80
131
81
132
pi_result OCL (piQueueCreate)(pi_context context, pi_device device,
@@ -290,7 +341,7 @@ _PI_CL(piDeviceRetain, clRetainDevice)
290
341
_PI_CL (piDeviceRelease, clReleaseDevice)
291
342
_PI_CL (piextDeviceSelectBinary, OCL(piextDeviceSelectBinary))
292
343
_PI_CL (piextGetDeviceFunctionPointer, OCL(piextGetDeviceFunctionPointer))
293
- // Context
344
+ // Context
294
345
_PI_CL (piContextCreate, clCreateContext)
295
346
_PI_CL (piContextGetInfo, clGetContextInfo)
296
347
_PI_CL (piContextRetain, clRetainContext)
0 commit comments