CLBufferRead

OpenCL 버퍼를 배열로 읽고 읽기 요소 수를 반환합니다.

uint  CLBufferRead(
   int          buffer,                    // OpenCL 버퍼에 대한 핸들
   const void&  data[],                    // 값들의 배열
   uint         buffer_offset=0,           // OpenCL 버퍼의 오프셋(바이트), 기본적으로 0
   uint         data_offset=0,             // 요소 배열의 오프셋, 기본적으로 0
   uint         data_count=WHOLE_ARRAY     // 기본적으로 전체 버퍼를 읽기 위한 버퍼의 값의 수
   );

행렬과 벡터를 처리하기 위한 버전이 있습니다.

OpenCL 버퍼를 매트릭스로 읽고 성공하면 true를 반환합니다.

uint  CLBufferRead(
   int           buffer,                    // OpenCL 버퍼에 대한 핸들
   uint          buffer_offset,             // OpenCL 버퍼의 오프셋(바이트)
   const matrxi& mat,                       // 버퍼에서 값을 수신하기 위한 행렬
   ulong         rows=-1,                   // 행렬의 행 수
   ulong         cols=-1                    // 행렬의 열 수
   );

OpenCL 버퍼를 벡터로 읽고 성공하면 true를 반환합니다.

uint  CLBufferRead(
   int           buffer,                    // OpenCL 버퍼에 대한 핸들
   uint          buffer_offset,             // OpenCL 버퍼의 오프셋(바이트)
   const vector& vec,                       // 버퍼에서 값을 수신하기 위한 벡터
   ulong         size-1,                    // 벡터 길이 
   );

Parameter

buffer

[in]   OpenCL 버퍼의 핸들.

data[]

[in]  OpenCL 버퍼에서 값을 수신하기 위한 배열. 참조에 의해 통과됨

buffer_offset

[in]  OpenCL 버퍼의 오프셋(바이트)이며, 여기서 읽기가 시작됩니다. 기본적으로 읽기는 버퍼의 처음 시작부터 시작합니다.

data_offset

[in]  OpenCL 버퍼의 값을 쓰기 위한 첫 번째 배열 요소의 인덱스. 기본적으로 읽기 값을 배열로 쓰는 작업은 제로 인덱스에서 시작됩니다.

data_count

[in]  읽어야 할 값의 수. 전체 OpenCL 버퍼는 기본적으로 읽힙니다.

mat

[out] 버퍼에서 데이터를 읽기 위한 행렬은 다음 세 가지 유형 중 하나일 수 있습니다 - matrix, matrixf 또는 matrixc.

vec

[out]  버퍼에서 데이터를 읽기 위한 벡터는 vector, vectorf 또는 vectorc의 세 가지 유형 중 하나일 수 있습니다.

rows=-1

[in] 매개변수가 지정되면 cols 매개변수도 지정되어야 합니다. 새 행렬의 차원을 지정하지 않으면 현재 차원이 사용됩니다. 값이 -1이면 행 수가 변경되지 않습니다.

cols=-1

[in] 매개변수를 지정하지 않으면 rows 매개변수도 건너뛰어야 합니다. 매트릭스는 규칙을 따릅니다: 두 매개변수가 모두 지정되거나 지정되지 않으면 오류가 발생합니다. 두 매개변수(rowscols)가 모두 지정되면 행렬 크기가 변경됩니다. -1의 경우 컬럼의 개수는 변하지 않습니다.

size=-1

[in] 매개변수가 지정되지 않았거나 값이 -1이면 벡터 길이가 변경되지 않습니다.

반환값

읽기 요소의 수. 오류 발생 시 0이 반환됩니다. 오류에 대한 자세한 내용은 GetLastError() 함수를 사용하십시오.

true 행렬 또는 벡터가 성공적으로 처리될 경우 그렇지 않을 경우 false.

참고

1차원 배열의 경우, OpenCL 버퍼에 데이터를 쓰기 시작하는 요소의 수는 AS_SERIES 플래그를 고려하여 계산됩니다.

2개 이상의 차원으로 구성된 배열은 1차원으로 표시됩니다. 이 경우 data_offset은 프레젠테이션에서 건너뛸 요소의 수이지 첫 번째 차원의 요소 수가 아닙니다.

방정식을 사용하여 Pi 계산 :

pi_calculation_formula

#define  _num_steps        1000000000
#define  _divisor          40000
#define  _step             1.0 / _num_steps
#define  _intrnCnt         _num_steps / _divisor
 
/+------------------------------------------------------------------+
//|                                                                 |
/+------------------------------------------------------------------+
string D2S(double argint digits) { return DoubleToString(argdigits); }
string I2S(int arg)                { return IntegerToString(arg); }
 
//--- OpenCL 프로그램 코드
const string clSource=
  "#define _step "+D2S(_step12)+"                   \r\n"
  "#define _intrnCnt "+I2S(_intrnCnt)+"               \r\n"
  "                                                   \r\n"
  "__kernel void Pi( __global double *out )           \r\n"
  "{                                                  \r\n"
  "  int i = get_global_id( 0 );                      \r\n"
  "  double partsum = 0.0;                            \r\n"
  "  double x = 0.0;                                  \r\n"
  "  long from = i * _intrnCnt;                       \r\n"
  "  long to = from + _intrnCnt;                      \r\n"
  "  for( long j = from; j < to; j ++ )               \r\n"
  "  {                                                \r\n"
  "     x = ( j + 0.5 ) * _step;                      \r\n"
  "     partsum += 4.0 / ( 1. + x * x );              \r\n"
  "  }                                                \r\n"
  "  out[ i ] = partsum;                              \r\n"
  "}                                                  \r\n";
 
/+------------------------------------------------------------------+
//| 프로그램 시작 함수 스크립트                                            |
/+------------------------------------------------------------------+
int OnStart()
 {
  Print("Pi Calculation: step = "+D2S(_step12)+"; _intrnCnt = "+I2S(_intrnCnt));
//--- OpenCL 컨텍스트 준비
  int clCtx;
  if((clCtx=CLContextCreate(CL_USE_GPU_ONLY))==INVALID_HANDLE)
   {
    Print("OpenCL not found");
    return(-1);
   }
  int clPrg = CLProgramCreate(clCtxclSource);
  int clKrn = CLKernelCreate(clPrg"Pi");
  int clMem=CLBufferCreate(clCtx_divisor*sizeof(double), CL_MEM_READ_WRITE);
  CLSetKernelArgMem(clKrn0clMem);
 
  const uint offs[1]  = {0};
  const uint works[1] = {_divisor};
//--- OpenCL 프로그램 실행
  ulong start=GetMicrosecondCount();
  if(!CLExecute(clKrn1offsworks))
   {
    Print("CLExecute(clKrn, 1, offs, works) failed! Error "GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    return(-1);
   }
//--- OpenCL 기기로부터 결과
  vector buffer(_divisor);
  if(!CLBufferRead(clMem0buffer))
   {
    Print("CLBufferRead(clMem, 0, buffer) failed! Error "GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    return(-1);
   }
//--- Pi를 계산하기 위해 모든 값을 더함
  double Pi=buffer.Sum()*_step;
 
  double time=(GetMicrosecondCount()-start)/1000.;
  Print("OpenCL: Pi calculated for "+D2S(time2)+" ms");
  Print("Pi = "+DoubleToString(Pi12));
//--- 메모리 비우기
  CLFreeAll(clMemclKrnclPrgclCtx);
//--- 성공
  return(0);
 }
  /*
  Pi Calculationstep = 0.000000001000_intrnCnt = 25000
  OpenCLGPU device 'Ellesmereselected
  OpenCLPi calculated for 99.98 ms
  Pi = 3.141592653590
  */ 
/+------------------------------------------------------------------+
//| 메모리를 확보하는 보조 루틴                                            |
/+------------------------------------------------------------------+
void CLFreeAll(const int clMemconst int clKrnconst int clPrgconst int clCtx)
 {
  CLBufferFree(clMem);
  CLKernelFree(clKrn);
  CLProgramFree(clPrg);
  CLContextFree(clCtx);
 }