CLBufferRead
Читает буфер OpenCL в массив и возвращает количество прочитанных элементов.
uint CLBufferRead( int buffer, const void& data[], uint buffer_offset=0, uint data_offset=0, uint data_count=WHOLE_ARRAY ); |
Существуют также версии для работы матрицами и векторами.
Читает буфер OpenCL в матрицу и возвращает true в случае успеха.
uint CLBufferRead( int buffer, uint buffer_offset, const matrix& mat, ulong rows=-1, ulong cols=-1 ); |
Читает буфер OpenCL в вектор и возвращает true в случае успеха.
uint CLBufferRead( int buffer, uint buffer_offset, const vector& vec, ulong size-1, ); |
Параметры
buffer
[in] Хендл буфера OpenCL.
data[]
[out] Массив для получения значений из буфера 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 также должен быть пропущен. Для матрицы действует правило: либо указаны оба параметра, либо ни одного, в противном случае возникнет ошибка. Если указаны об параметра (rows и cols), то размер матрицы будет изменен. Если значение равно -1, то число столбцов не изменится.
size=-1
[in] Если параметр не указан или значение равно -1, то длина вектора не изменится.
Возвращаемое значение
Примечание
Пример вычисления числа Pi по формуле:

#define _num_steps 1000000000 #define _divisor 40000 #define _step 1.0 / _num_steps #define _intrnCnt _num_steps / _divisor //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ string D2S(double arg, int digits) {return DoubleToString(arg, digits);} string I2S(int arg) {return IntegerToString(arg);} //--- код OpenCL программы const string clSource= "#define _step "+D2S(_step, 12)+" \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"; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ int OnStart() { Print("Pi Calculation: step = "+D2S(_step, 12)+"; _intrnCnt = "+I2S(_intrnCnt)); //--- создадим OpenCL контексты int clCtx; if((clCtx=CLContextCreate(CL_USE_GPU_ONLY))==INVALID_HANDLE) { Print("OpenCL not found"); return(-1); } int clPrg = CLProgramCreate(clCtx, clSource); int clKrn = CLKernelCreate(clPrg, "Pi"); int clMem=CLBufferCreate(clCtx, _divisor*sizeof(double), CL_MEM_READ_WRITE); CLSetKernelArgMem(clKrn, 0, clMem); const uint offs[1] = {0}; const uint works[1] = {_divisor}; //--- запускаем OpenCL программу ulong start=GetMicrosecondCount(); if(!CLExecute(clKrn, 1, offs, works)) { Print("CLExecute(clKrn, 1, offs, works) failed! Error ", GetLastError()); CLFreeAll(clMem, clKrn, clPrg, clCtx); return(-1); } //--- получим результаты вычисления из OpenCL vector buffer(_divisor); if(!CLBufferRead(clMem, 0, buffer)) { Print("CLBufferRead(clMem, 0, buffer) failed! Error ", GetLastError()); CLFreeAll(clMem, clKrn, clPrg, clCtx); return(-1); } //--- просуммируем все значения для вычисления Pi double Pi=buffer.Sum()*_step; double time=(GetMicrosecondCount()-start)/1000.; Print("OpenCL: Pi calculated for "+D2S(time, 2)+" ms"); Print("Pi = "+DoubleToString(Pi, 12)); //--- освободим все OpenCL контексты CLFreeAll(clMem, clKrn, clPrg, clCtx); //--- успешно return(0); } /* Pi Calculation: step = 0.000000001000; _intrnCnt = 25000 OpenCL: GPU device 'Ellesmere' selected OpenCL: Pi calculated for 99.98 ms Pi = 3.141592653590 */ //+------------------------------------------------------------------+ //| Освободим все OpenCL контексты | //+------------------------------------------------------------------+ void CLFreeAll(const int clMem, const int clKrn, const int clPrg, const int clCtx) { CLBufferFree(clMem); CLKernelFree(clKrn); CLProgramFree(clPrg); CLContextFree(clCtx); } |