1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
#if defined(TEST_OPENCL)
// Implement OpenCL custom context.
#define CL_TARGET_OPENCL_VERSION 120
#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif
// Create the global context. This is just a helper function not called by Halide.
bool create_opencl_context(cl_context &cl_ctx, cl_command_queue &cl_q) {
cl_int err = 0;
const cl_uint maxPlatforms = 4;
cl_platform_id platforms[maxPlatforms];
cl_uint platformCount = 0;
err = clGetPlatformIDs(maxPlatforms, platforms, &platformCount);
if (err != CL_SUCCESS) {
printf("clGetPlatformIDs failed (%d)\n", err);
return false;
}
cl_platform_id platform = nullptr;
if (platformCount > 0) {
platform = platforms[0];
}
if (platform == nullptr) {
printf("Failed to get platform\n");
return false;
}
cl_device_type device_type = CL_DEVICE_TYPE_ALL;
// Make sure we have a device
const cl_uint maxDevices = 4;
cl_device_id devices[maxDevices];
cl_uint deviceCount = 0;
err = clGetDeviceIDs(platform, device_type, maxDevices, devices, &deviceCount);
if (err != CL_SUCCESS) {
printf("clGetDeviceIDs failed (%d)\n", err);
return false;
}
if (deviceCount == 0) {
printf("Failed to get device\n");
return false;
}
cl_device_id dev = devices[deviceCount - 1];
// Create context and command queue.
cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform,
0};
cl_ctx = clCreateContext(properties, 1, &dev, nullptr, nullptr, &err);
if (err != CL_SUCCESS) {
printf("clCreateContext failed (%d)\n", err);
return false;
}
cl_q = clCreateCommandQueue(cl_ctx, dev, 0, &err);
if (err != CL_SUCCESS) {
printf("clCreateCommandQueue failed (%d)\n", err);
return false;
}
return true;
}
void destroy_opencl_context(cl_context cl_ctx, cl_command_queue cl_q) {
clReleaseCommandQueue(cl_q);
clReleaseContext(cl_ctx);
}
#elif defined(TEST_CUDA)
// Implement CUDA custom context.
#include <cuda.h>
bool create_cuda_context(CUcontext &cuda_ctx) {
// Initialize CUDA
CUresult err = cuInit(0);
if (err != CUDA_SUCCESS) {
printf("cuInit failed (%d)\n", err);
return false;
}
// Make sure we have a device
int deviceCount = 0;
err = cuDeviceGetCount(&deviceCount);
if (err != CUDA_SUCCESS) {
printf("cuGetDeviceCount failed (%d)\n", err);
return false;
}
if (deviceCount <= 0) {
printf("No CUDA devices available\n");
return false;
}
CUdevice dev;
// Get device
CUresult status;
// Try to get a device >0 first, since 0 should be our display device
// For now, don't try devices > 2 to maintain compatibility with previous behavior.
if (deviceCount > 2) deviceCount = 2;
for (int id = deviceCount - 1; id >= 0; id--) {
status = cuDeviceGet(&dev, id);
if (status == CUDA_SUCCESS) break;
}
if (status != CUDA_SUCCESS) {
printf("Failed to get CUDA device\n");
return status;
}
// Create context
err = cuCtxCreate(&cuda_ctx, 0, dev);
if (err != CUDA_SUCCESS) {
printf("cuCtxCreate failed (%d)\n", err);
return false;
}
return true;
}
void destroy_cuda_context(CUcontext cuda_ctx) {
cuCtxDestroy(cuda_ctx);
}
#elif defined(TEST_METAL) && defined(__OBJC__)
#include <Metal/MTLCommandQueue.h>
#include <Metal/MTLDevice.h>
bool create_metal_context(id<MTLDevice> &device, id<MTLCommandQueue> &queue) {
device = MTLCreateSystemDefaultDevice();
if (device == nullptr) {
NSArray<id<MTLDevice>> *devices = MTLCopyAllDevices();
if (devices != nullptr) {
device = devices[0];
}
}
if (device == nullptr) {
printf("Failed to find Metal device.\n");
return false;
}
queue = [device newCommandQueue];
if (queue == nullptr) {
printf("Failed to create Metal command queue.\n");
return false;
}
return true;
}
void destroy_metal_context(id<MTLDevice> device, id<MTLCommandQueue> queue) {
[queue release];
[device release];
}
#endif
|