added C version of example02

This commit is contained in:
Dakota St. Laurent
2015-07-16 00:04:40 -04:00
committed by dhstlaur
parent 15d0ffaac2
commit c8179b88a7
3 changed files with 102 additions and 3 deletions

3
.gitignore vendored
View File

@@ -3,5 +3,4 @@
# THIS IS MY SWAP # THIS IS MY SWAP
# (vim swap files) # (vim swap files)
*.swp .*.s??
*.swo

View File

@@ -7,12 +7,18 @@ This code uses OpenCL 1.1 on a NVIDIA GPU.
### Linux ### Linux
(Only tested on Ubuntu). For NVIDIA GPUs, I've installed the following packages: `nvidia-346 nvidia-346-dev nvidia-346-uvm nvidia-libopencl1-346 nvidia-modprobe nvidia-opencl-icd-346 nvidia-settings`. Since the `opencl-headers` package in the main repository is for OpenCL 1.2, you can get the OpenCL 1.1 header files from [here](http://packages.ubuntu.com/precise/opencl-headers). (Only tested on Ubuntu). For NVIDIA GPUs, I've installed the following packages: `nvidia-346 nvidia-346-dev nvidia-346-uvm nvidia-libopencl1-346 nvidia-modprobe nvidia-opencl-icd-346 nvidia-settings`. Since the `opencl-headers` package in the main repository is for OpenCL 1.2, you can get the OpenCL 1.1 header files from [here](http://packages.ubuntu.com/precise/opencl-headers).
Then to compile: Then to compile the C++ code:
``` ```
g++ -std=c++0x main.cpp -o main.out -lOpenCL g++ -std=c++0x main.cpp -o main.out -lOpenCL
``` ```
To compile the C code:
```
gcc main.c -o main.out -lOpenCL
```
### OS X ### OS X
OpenCL is installed on OS X by default, but since this code uses the C++ bindings, you'll need to get that too. Get the [official C++ bindings from the OpenCL registr](https://www.khronos.org/registry/cl/api/1.1/cl.hpp) and copy it to the OpenCL framework directory, or do the following: OpenCL is installed on OS X by default, but since this code uses the C++ bindings, you'll need to get that too. Get the [official C++ bindings from the OpenCL registr](https://www.khronos.org/registry/cl/api/1.1/cl.hpp) and copy it to the OpenCL framework directory, or do the following:

94
example02/main.c Normal file
View File

@@ -0,0 +1,94 @@
#include <stdlib.h>
#include <stdio.h>
#include <CL/cl.h>
const char *kernel_code =
"__kernel void multiply_by(__global int* A, const int c) {"
" A[get_global_id(0)] = c * A[get_global_id(0)];"
"}";
int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n-1);
}
int main( void ) {
// OpenCL related declarations
cl_int err;
cl_platform_id platform;
cl_device_id device;
cl_context_properties props[3] = { CL_CONTEXT_PLATFORM, 0, 0 };
cl_context ctx;
cl_program program;
cl_command_queue queue;
cl_event event = NULL;
cl_kernel k_multiplyby;
int i;
//
const size_t N = 1024; // vector size
const int c_max = 5; // max value to iterate to
const int coeff = factorial(c_max);
int *A, *B, *C; // A is initial, B is result, C is expected result
A = (int*) malloc(N * sizeof(*A));
B = (int*) malloc(N * sizeof(*B));
C = (int*) malloc(N * sizeof(*C));
for (i=0; i<N; i++) {
A[i] = i;
C[i] = coeff*i;
}
cl_mem d_A; // buffer object for A
/* Setup OpenCL environment. */
err = clGetPlatformIDs( 1, &platform, NULL );
err = clGetDeviceIDs( platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL );
props[1] = (cl_context_properties)platform;
ctx = clCreateContext( props, 1, &device, NULL, NULL, &err );
queue = clCreateCommandQueue( ctx, device, 0, &err );
program = clCreateProgramWithSource(ctx, 1, (const char **) &kernel_code, NULL, &err);
err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
k_multiplyby = clCreateKernel(program, "multiply_by", &err);
// initialize buffer with data
d_A = clCreateBuffer( ctx, CL_MEM_READ_WRITE, N*sizeof(*A), NULL, &err );
err = clEnqueueWriteBuffer( queue, d_A, CL_TRUE, 0, N*sizeof(*A), A, 0, NULL, NULL );
clSetKernelArg(k_multiplyby, 0, sizeof(cl_mem), &d_A);
int c;
for (c=2; c<=c_max; c++) {
clSetKernelArg(k_multiplyby, 1, sizeof(int), &c);
clEnqueueNDRangeKernel(queue, k_multiplyby, 1, NULL, &N, &N, 0, NULL, NULL);
}
err = clFinish(queue);
err = clEnqueueReadBuffer( queue, d_A, CL_TRUE, 0, N*sizeof(*B), B, 0, NULL, NULL );
err = clFinish(queue);
int success = 1;
for (i=0; i<N; i++) {
if (B[i] != C[i]) {
success = 0;
break;
}
}
if (success)
printf("Arrays are equal!\n");
else
printf("Arrays are NOT equal\n");
/* Release OpenCL memory objects. */
clReleaseMemObject( d_A );
free(A);
free(B);
free(C);
clReleaseCommandQueue( queue );
clReleaseContext( ctx );
return 0;
}