CLBufferRead

Legge un buffer OpenCL in un array e restituisce il numero di elementi letti.

uint  CLBufferRead(
   int          buffer,                    // Un handle per un buffer OpenCL
   const void&  data[],                    // Un array di valori
   uint         buffer_offset=0,           // Un offset nel buffer OpenCL in bytes, 0 per default
   uint         data_offset=0,             // Un offset negli elementi dell' array, 0 per default
   uint         data_count=WHOLE_ARRAY     // Il numero di valori dal buffer per la lettura, l'intero buffer per default
   );

Ci sono anche versioni per la gestione di matrici e vettori.

Legge il buffer OpenCL nella matrice e restituisce true in caso di esito positivo.

uint  CLBufferRead(
   int           buffer,                    // un handle al buffer OpenCL
   uint          buffer_offset,             // uno scostamento nel buffer OpenCL in byte
   const matrix& mat,                       // la matrice per ricevere i valori dal buffer
   ulong         rows=-1,                   // il numero di righe nella matrice
   ulong         cols=-1                    // il numero di colonne nella matrice
   );

Legge il buffer OpenCL nel vettore e restituisce true in caso di esito positivo.

uint  CLBufferRead(
   int           buffer,                    // un handle al buffer OpenCL
   uint          buffer_offset,             // uno scostamento nel buffer OpenCL in byte
   const vector& vec,                       // il vettore per ricevere i valori dal buffer
   ulong         size-1,                    // lunghezza del vettore 
   );

Parametri

buffer

[in]   Un handle del buffer OpenCL .

data[]

[in]  Un array per ricevere valori dal buffer OpenCL. Passato per riferimento.

buffer_offset

[in] Un offset nel buffer OpenCL in byte, da cui inizia la lettura. Per default, la lettura inizia proprio dall'inizio inizio, del buffer.

data_offset

[in] L'indice del primo elemento della matrice per scrivere i valori del buffer OpenCL. Per default, la scrittura dei valori letti in un array inizia dall'indice zero.

data_count

[in] Il numero di valori che devono essere letti. L'intero buffer OpenCL viene letto per impostazione predefinita.

mat

[out]  La matrice per la lettura dei dati dal buffer può essere uno qualsiasi dei tre tipi: matrix, matrixf o matrixc.

vec

[out]  Il vettore per la lettura dei dati dal buffer può essere di uno qualsiasi dei tre tipi — vector, vectorf or vectorc.

rows=-1

[in]  Se il parametro è specificato, è necessario specificare anche il parametro cols. Se non vengono specificate le nuove dimensioni della matrice, vengono utilizzate quelle correnti. Se il valore è -1, il numero di righe non cambia.

cols=-1

[in]  Se il parametro non è specificato, anche il parametro rows deve essere ignorato. La matrice rispetta la regola: o sono specificati entrambi i parametri o nessuno, altrimenti si verificherà un errore. Se vengono specificati entrambi i parametri (rows e cols), la dimensione della matrice viene modificata. In caso di -1, il numero di colonne non cambia.

size=-1

[in]  Se il parametro non è specificato o il suo valore è -1, la lunghezza del vettore non cambia.

Valore restituito

Il numero di elementi di lettura. 0 viene restituito in caso di errore. Per ulteriori informazioni sull'errore, utilizzare la funzione GetLastError().

true se una matrice o un vettore vengono gestiti correttamente, altrimenti false.

Nota

Per array uni-dimensionali, il numero dell'elemento, in cui la scrittura di dati in un inizio di buffer OpenCL, viene calcolata tenendo conto delle flags AS_SERIES.

Un array di due o più dimensioni è presentata come uni-dimensionale. In questo caso, data_offset è il numero di elementi che devono essere saltati nella presentazione, non il numero di elementi nella prima dimensione.

Esempio calcolo di Pi utilizzando l'equazione:

pi_calculation_formula

#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); }
 
//--- Codice programma 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";
 
//+------------------------------------------------------------------+
//| Programma Script funzione start                                  |
//+------------------------------------------------------------------+
int OnStart()
 {
  Print("Pi Calculation: step = "+D2S(_step, 12)+"; _intrnCnt = "+I2S(_intrnCnt));
//--- prepara i contesti 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};
//--- avvia il programma 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);
   }
//--- ottieni risultati dal dispositivo OpenCL
  vector buffer(_divisor);
  if(!CLBufferRead(clMem, 0, buffer))
   {
    Print("CLBufferRead(clMem, 0, buffer) failed! Error ", GetLastError());
    CLFreeAll(clMem, clKrn, clPrg, clCtx);
    return(-1);
   }
//--- somma tutti i valori per calcolare 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));
//--- libera memoria 
  CLFreeAll(clMem, clKrn, clPrg, clCtx);
//--- esito positivo
  return(0);
 }
  /*
  Pi Calculation: step = 0.000000001000; _intrnCnt = 25000
  OpenCL: GPU device 'Ellesmere' selected
  OpenCL: Pi calculated for 99.98 ms
  Pi = 3.141592653590
  */ 
//+------------------------------------------------------------------+
//| Routine ausiliaria per liberare memoria                          |
//+------------------------------------------------------------------+
void CLFreeAll(const int clMem, const int clKrn, const int clPrg, const int clCtx)
 {
  CLBufferFree(clMem);
  CLKernelFree(clKrn);
  CLProgramFree(clPrg);
  CLContextFree(clCtx);
 }