以下は、2つの2D配列を追加するために作成したコードです。コンパイルされますが、実行しようとすると、次のように表示されます:エラー:プログラムのビルドに失敗しました。runtime0.0000 prpgramがビルドされないのはなぜですか?また、クエリしたビルドログが表示されないのはなぜですか?実際、私は配列を初期化しているだけなので、2dから1dへの変換を示していない、1d配列に直接保存しました。
コード:
# include <stdio.h>
#include <stdlib.h>
#ifdef APPLE
#include<OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
#define order 1000
#define MAX_SOURCE_SIZE (0x100000)
int main(int argc, char **argv)
{
float *A;
float *B;
float *C;
int n,m,p;
int err;
int szA, szB,szC;
cl_device_id device_id;
cl_context context;
cl_command_queue commands;
cl_program program;
cl_kernel kernel;
cl_uint nd;
cl_mem a_in;
cl_mem b_in;
cl_mem c_out;
int i,j;
n=order;
m=order;
p=order;
size_t global[2];
nd=1;
cl_uint numPlatforms;
cl_platform_id firstPlatformId;
szA=n*p;
szB=p*m;
szC=n*m;
A=(float *)malloc(sizeof(float)*szA);
B=(float *)malloc(sizeof(float)*szB);
C=(float *)malloc(sizeof(float)*szC);
for(i=0; i<order; i++)
for(j=0; j<order; j++)
A[i*m+j]=i;
B[i*m+j]=i;
FILE *fp;
char fileName[] = "./array_add_kernel.cl";
char *source_str;
size_t source_size;
fp = fopen(fileName, "r");
if (!fp) {
fprintf(stderr, "Failed to load kernel.\n");
exit(1);
}
source_str = (char*)malloc(MAX_SOURCE_SIZE);
source_size = fread( source_str, 1, MAX_SOURCE_SIZE, fp);
fclose( fp );
err=clGetPlatformIDs(1, &firstPlatformId, &numPlatforms);
err=clGetDeviceIDs(firstPlatformId, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
cl_context_properties conpro[]={ CL_CONTEXT_PLATFORM,(cl_context_properties) firstPlatformId, 0};
context=clCreateContext(conpro, 1, &device_id, NULL, NULL, &err);
commands=clCreateCommandQueue(context, device_id,CL_QUEUE_PROFILING_ENABLE, &err);
a_in= clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float)*szA, NULL, NULL);
b_in= clCreateBuffer(context, CL_MEM_READ_ONLY, sizeof(float)*szB, NULL, NULL);
c_out= clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(float)*szC, NULL, NULL);
program= clCreateProgramWithSource(context, 1, (const char**)&source_str,(const size_t *)&source_size, &err);
err= clBuildProgram(program,0, NULL, NULL, NULL, NULL );
if(err!= CL_SUCCESS)
{
size_t len;
char buffer[2048];
printf("Error:Failed to build program executable!");
clGetProgramBuildInfo(program,device_id,CL_PROGRAM_BUILD_LOG,sizeof(buffer),buffer,&len);
printf("%s \n",buffer);
}
kernel= clCreateKernel(program, "array_add_kernel", &err);
err= 0;
err= clSetKernelArg(kernel, 0, sizeof(int), &n);
err|= clSetKernelArg(kernel, 1, sizeof(int), &p);
err|= clSetKernelArg(kernel, 2, sizeof(int), &m);
err|= clSetKernelArg(kernel, 3, sizeof(cl_mem), &a_in);
err|= clSetKernelArg(kernel, 4, sizeof(cl_mem), &b_in);
err|= clSetKernelArg(kernel, 5, sizeof(cl_mem), &c_out);
err=clEnqueueWriteBuffer(commands, a_in, CL_TRUE, 0, sizeof(float)*szA, A, 0, NULL, NULL);
err= clEnqueueWriteBuffer(commands, a_in, CL_TRUE, 0, sizeof(float)*szB, B, 0, NULL, NULL);
cl_event prof_event;
global[0]= (size_t)n;
global[1]=(size_t)m;
err=clEnqueueNDRangeKernel(commands, kernel, nd, NULL, global, NULL, 0, NULL, &prof_event);
clFinish(commands);
cl_ulong ev_start_time=(cl_ulong)0;
cl_ulong ev_end_time=(cl_ulong)0;
size_t ret_size;
err= clGetEventProfilingInfo(prof_event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &ev_start_time, NULL);
err= clGetEventProfilingInfo(prof_event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &ev_end_time, NULL);
err=clEnqueueReadBuffer(commands,c_out,CL_TRUE,0,sizeof(float)*szC,C,0,NULL,NULL);
cl_float runtime=(ev_end_time-ev_start_time)*1.0e-9;
printf("Runtime:%f ",runtime);
clReleaseProgram(program);
clReleaseKernel(kernel);
clReleaseMemObject(a_in);
clReleaseMemObject(b_in);
clReleaseMemObject(c_out);
clReleaseCommandQueue(commands);
clReleaseContext(context);
}
カーネル:
kernel void array_add_kernel(
const int n, const int m, const p, _global const float * A, _global const float * B, , _global float * C )
{
int i= get_global_id(0);
int j= get_global_id(1);
C[i*m + j] = A[i*m + j] + B[i*m + j];
}