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 argint digits) { return DoubleToString(argdigits); }
string I2S(int arg)                { return IntegerToString(arg); }
 
//--- Codice programma 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";
 
//+------------------------------------------------------------------+
//| Programma Script funzione start                                  |
//+------------------------------------------------------------------+
int OnStart()
 {
  Print("Pi Calculation: step = "+D2S(_step12)+"; _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(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};
//--- avvia il programma OpenCL
  ulong start=GetMicrosecondCount();
  if(!CLExecute(clKrn1offsworks))
   {
    Print("CLExecute(clKrn, 1, offs, works) failed! Error "GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    return(-1);
   }
//--- ottieni risultati dal dispositivo OpenCL
  vector buffer(_divisor);
  if(!CLBufferRead(clMem0buffer))
   {
    Print("CLBufferRead(clMem, 0, buffer) failed! Error "GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    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(time2)+" ms");
  Print("Pi = "+DoubleToString(Pi12));
//--- libera memoria 
  CLFreeAll(clMemclKrnclPrgclCtx);
//--- esito positivo
  return(0);
 }
  /*
  Pi Calculationstep = 0.000000001000_intrnCnt = 25000
  OpenCLGPU device 'Ellesmereselected
  OpenCLPi calculated for 99.98 ms
  Pi = 3.141592653590
  */ 
//+------------------------------------------------------------------+
//| Routine ausiliaria per liberare memoria                          |
//+------------------------------------------------------------------+
void CLFreeAll(const int clMemconst int clKrnconst int clPrgconst int clCtx)
 {
  CLBufferFree(clMem);
  CLKernelFree(clKrn);
  CLProgramFree(clPrg);
  CLContextFree(clCtx);
 }