Blob Blame History Raw
#include <stdio.h>
#include <string.h>
#include <CL/cl.h>

int main() {
  cl_int ret;

  cl_uint num_platforms;
  cl_platform_id *platforms;
  cl_platform_id pocl_platform = NULL;
  unsigned i;
  cl_uint num_devices;
  cl_device_id device;
  cl_context context;
  const char* src = "kernel void test(global float *out) { *out = M_PI_F; }";
  size_t src_len = strlen(src) + 1;
  cl_program program;
  cl_kernel kernel;
  float out;
  cl_mem buffer;
  cl_command_queue queue;
  size_t global_work_size = 1;

  ret = clGetPlatformIDs(0, NULL, &num_platforms);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  platforms = malloc(num_platforms * sizeof(cl_platform_id));
  if (!platforms)
    return EXIT_FAILURE;

  ret = clGetPlatformIDs(num_platforms, platforms, NULL);

  for (i = 0; i < num_platforms; i++) {
    char *platform_name;
    char *platform_vendor;
    size_t param_size;
    cl_platform_id platform = platforms[i];

    /* Get platform name */
    ret = clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, NULL, &param_size);
    if (ret != CL_SUCCESS)
      return EXIT_FAILURE;

    platform_name = malloc(param_size);
    if (!platform_name)
      return EXIT_FAILURE;

    ret = clGetPlatformInfo(platform, CL_PLATFORM_NAME, param_size,
          platform_name, NULL);

    if (ret != CL_SUCCESS)
      return EXIT_FAILURE;

    if (!strcmp(platform_name, "Portable Computing Language")) {
      pocl_platform = platform;
      free(platform_name);
      break;
    }

    free(platform_name);
  }

  if (!pocl_platform)
    return EXIT_FAILURE;

  ret = clGetDeviceIDs(pocl_platform, CL_DEVICE_TYPE_CPU, 0, NULL,
                       &num_devices);
  if (ret != CL_SUCCESS || num_devices < 1)
    return EXIT_FAILURE;

  ret = clGetDeviceIDs(pocl_platform, CL_DEVICE_TYPE_CPU, 1, &device, NULL);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  context = clCreateContext(NULL, 1, &device, NULL, NULL, &ret);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  program = clCreateProgramWithSource(context, 1, &src, &src_len, &ret);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  ret = clBuildProgram(program, 1, &device, NULL, NULL, NULL);
  if (ret != CL_SUCCESS) {
    size_t param_size;
    char *log;
    ret = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL,
                                &param_size);
    if (ret != CL_SUCCESS)
      return EXIT_FAILURE;

    log = malloc(param_size);
    ret = clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, param_size,
                                log, NULL);
    if (ret != CL_SUCCESS)
      return EXIT_FAILURE;
    
    fprintf(stderr, "%s\n", log);
    return EXIT_FAILURE;
  }

  kernel = clCreateKernel(program, "test", &ret);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  buffer = clCreateBuffer(context, CL_MEM_USE_HOST_PTR, sizeof(out), &out, &ret);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  ret = clSetKernelArg(kernel, 0, sizeof(buffer), &buffer);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  queue = clCreateCommandQueue(context, device, 0, &ret);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  ret = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_work_size, NULL,
                               0, NULL, NULL);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  ret = clFinish(queue);
  if (ret != CL_SUCCESS)
    return EXIT_FAILURE;

  printf("pi = %f\n", out);
  if (out != CL_M_PI_F)
    return EXIT_FAILURE;

  return EXIT_SUCCESS;
}