DGL
https://delphigl.com/forum/

OpenCL basic question?
https://delphigl.com/forum/viewtopic.php?f=19&t=10497
Seite 1 von 1

Autor:  ina [ Mi Jul 04, 2012 07:38 ]
Betreff des Beitrags:  OpenCL basic question?

I am learning OpenCL. I need to implement binary search algorithm but I got stucked. I use OpenCL example from http://www.heatlab.cz/OpenCLforDelphi.html . There is MyFirstOpenCL demo in archive and this what I have done.

In FMain.pas:

Code:
  1.  
  2. procedure TFormMain.BtnTestProgramClick(Sender: TObject);
  3. const
  4.   MYSIZE=5;
  5.   // Some interesting data for the vectors
  6.   //InitialData1: array[0..13] of cl_int = (0,3,6,7,9,11,13,14,15,17,22,33,44,66);
  7.   InitialData1: array[0..6] of cl_int = (0,3,6,7,9,11,22);//,13,14,15,17,22,33,44,66);
  8.   InitialData2: array[0..0] of cl_int = (11);
  9. var
  10.   i: integer;
  11.     HostVector1, HostVector2, HostOutputVector: array[0..MYSIZE-1] of cl_int;
  12.   sourceStr: string;
  13.   sourceSize: size_t;
  14.   sourcePChar: PChar;
  15.   OpenCLProgram: cl_program;
  16.   OpenCLVectorAdd: cl_kernel;
  17.   CommandQueue: cl_command_queue;
  18.   GPUVector1, GPUVector2, GPUOutputVector: cl_mem;
  19.   globalThreads: array[0..0] of size_t;
  20.   //localThreads: array[0..0] of size_t;
  21.   s, error_string: string;
  22.   returned_size: size_t;
  23. begin
  24.   Cursor:=crHourGlass;
  25.   ////////////////
  26.   // Init Context
  27.   if ListCouple.ItemIndex<0 then begin
  28.     ShowMessage('Select couple!');
  29.     Cursor:=crDefault;
  30.     exit;
  31.   end;
  32.     // Get compute devices from platform
  33.     errcode_ret:=clGetDeviceIDs(platform_devices[ListCouple.ItemIndex].platform_id, platform_devices[ListCouple.ItemIndex].device_type, 0, nil, @num_devices_returned);
  34.   SetLength(device_ids, num_devices_returned);
  35.   errcode_ret:=clGetDeviceIDs(platform_devices[ListCouple.ItemIndex].platform_id, platform_devices[ListCouple.ItemIndex].device_type, num_devices_returned, @device_ids[0], @num_devices_returned);
  36.   if (errcode_ret<>CL_SUCCESS) then begin
  37.     ShowMessage('Error: Failed to create a device group!');
  38.     Cursor:=crDefault;
  39.     exit;
  40.   end;
  41.     // Create a compute context
  42.     context:=clCreateContext(nil, num_devices_returned, @device_ids[0], nil, nil, @errcode_ret);
  43.   if (errcode_ret<>CL_SUCCESS) then begin
  44.     ShowMessage('Error: Failed to create a compute context!!');
  45.     Cursor:=crDefault;
  46.     exit;
  47.   end;
  48.   // End (Init Context)
  49.   ////////////////
  50.  
  51.     // Initialize with some interesting repeating data
  52.     for i:=0 to MYSIZE-1 do begin
  53.         HostVector1[i]:=InitialData1[i mod 20];
  54.  
  55.     end;
  56.  HostVector2[0]:=InitialData2[0 mod 13];
  57.   // Create OpenCL program with source code
  58.   sourceStr:=convertToString('VectorAdd.cl');
  59.   sourceSize:=Length(sourceStr);
  60.   sourcePChar:=PChar(sourceStr);
  61.   OpenCLProgram := clCreateProgramWithSource(context, 1, @sourcePChar, @sourceSize, @errcode_ret);
  62.     if errcode_ret<>CL_SUCCESS then begin
  63.     ShowMessage('Error: clCreateProgramWithSource failed!');
  64.     clReleaseContext(context);
  65.     Cursor:=crDefault;
  66.     exit;
  67.   end;
  68.  
  69.     // Build the program (OpenCL JIT compilation)
  70.     if CL_SUCCESS<>clBuildProgram(OpenCLProgram, 0, nil, nil, nil, nil) then begin
  71.     error_string:='Error: clBuildProgram failed! ';
  72.     clGetProgramBuildInfo(OpenCLProgram, device_ids[0], CL_PROGRAM_BUILD_LOG, 0, nil, @returned_size);
  73.     SetLength(s, returned_size+2);
  74.     clGetProgramBuildInfo(OpenCLProgram, device_ids[0], CL_PROGRAM_BUILD_LOG, Length(s), PChar(s), @returned_size);
  75.     SetLength(s, Min(Pos(#0, s)-1, returned_size-1));
  76.     error_string:=error_string+s;
  77.  
  78.     ShowMessage(error_string);
  79.     clReleaseProgram(OpenCLProgram);
  80.     clReleaseContext(context);
  81.     Cursor:=crDefault;
  82.     exit;
  83.   end;
  84.     // Create a handle to the compiled OpenCL function (Kernel)
  85.     OpenCLVectorAdd:=clCreateKernel(OpenCLProgram, PChar('VectorAdd'), nil);
  86.  
  87.     // Create a command-queue on the first CPU or GPU device
  88.     CommandQueue:=clCreateCommandQueue(context, device_ids[0], 0, nil);
  89.  
  90.     // Allocate GPU memory for source vectors AND initialize from CPU memory
  91.     GPUVector1:=clCreateBuffer(context, CL_MEM_READ_ONLY or CL_MEM_COPY_HOST_PTR, sizeof(HostVector1[0]) * MYSIZE, @HostVector1[0], nil);
  92.     GPUVector2:=clCreateBuffer(context, CL_MEM_READ_ONLY or CL_MEM_COPY_HOST_PTR, sizeof(HostVector2[0]) * MYSIZE, @HostVector2[0], nil);
  93.     // Allocate output memory on GPU
  94.     GPUOutputVector:=clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(HostOutputVector[0]) * MYSIZE, nil, nil);
  95.     // In the next step we associate the GPU memory with the Kernel arguments
  96.     clSetKernelArg(OpenCLVectorAdd, 0, sizeof(cl_mem), @GPUOutputVector);
  97.     clSetKernelArg(OpenCLVectorAdd, 1, sizeof(cl_mem), @GPUVector1);
  98.     clSetKernelArg(OpenCLVectorAdd, 2, sizeof(cl_mem), @GPUVector2);
  99.     // Launch the Kernel on the GPU
  100.   globalThreads[0]:=MYSIZE;
  101.   //localThreads[0]:=1;
  102.     clEnqueueNDRangeKernel(CommandQueue, OpenCLVectorAdd, 1, nil, @globalThreads, nil, 0, nil, nil);
  103.     // Copy the output in GPU memory back to CPU memory
  104.     clEnqueueReadBuffer(CommandQueue, GPUOutputVector, CL_TRUE, 0, sizeof(HostOutputVector[0]) * MYSIZE, @HostOutputVector[0], 0, nil, nil);
  105.   // Free memory
  106.     clReleaseMemObject(GPUVector1);
  107.     clReleaseMemObject(GPUVector2);
  108.     clReleaseMemObject(GPUOutputVector);
  109.     clReleaseCommandQueue(CommandQueue);
  110.     clReleaseKernel(OpenCLVectorAdd);
  111.   clReleaseProgram(OpenCLProgram);
  112.     clReleaseContext(context);
  113.   // List results
  114.   ListOutput.Clear;
  115.   ListOutput.Items.Add( inttostr(HostOutputVector[0])); // result
  116.   //for i:=0 to MYSIZE-1 do ListOutput.Items.Add(Format('%d + %d = %d', [HostVector1[i], HostVector2[0], HostOutputVector[i]]));
  117.   Cursor:=crDefault;
  118. end;
  119.  


and code in VectorAdd.cl (I have not edit the file name or function name):
Code:
  1.  
  2. int binarySearch(__global read_only int* arr, __global read_only int* value) {
  3.    
  4.     int left=0;
  5.     int right=6;
  6.      
  7.       while (left <= right) {
  8.  
  9.             int middle = (left + right) / 2;
  10.  
  11.             if (arr[middle] == *value)
  12.  
  13.                   return middle;
  14.  
  15.             else if (arr[middle] > *value)
  16.  
  17.                   right = middle - 1;
  18.  
  19.             else
  20.  
  21.                   left = middle + 1;
  22.  
  23.       }
  24.  
  25.       return -1;
  26.  
  27. }
  28.  
  29. __kernel void VectorAdd(__global int* c, __global int* a,__global int* b)
  30. {
  31.    
  32.     unsigned int n = get_global_id(0);
  33.         c[n] = binarySearch(a,b);
  34.  
  35. }
  36.  


In FMain.pas, InitialData2 is 11. The binary search produced wrong result (-1). If the InitialData2 is 0 or 3 or 6 or 7 or 9 then result is correct. What have I missed? Please help me.

Seite 1 von 1 Alle Zeiten sind UTC + 1 Stunde
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/