CLBufferRead

Liest den OpenCL-Puffer in ein Array und gibt die Anzahl der gelesenen Elemente zurück.

uint  CLBufferRead(
   int          buffer,                    // Handle auf den OpenCL-Puffer
   const void&  data[],                    // Array von Werten
   uint         buffer_offset=0,           // Offset im OpenCL-Puffer in Bytes, standardmäßig 0
   uint         data_offset=0,             // Offset im Array in Elemente, standardmäßig 0
   uint         data_count=WHOLE_ARRAY     // Anzahl der Werte aus dem Puffer zu lesen, standardmäßig der gesamte Puffer
   );

Es gibt auch Versionen für die Verarbeitung von Matrizen und Vektoren.

Lesen der OpenCL-Puffer in die Matrix und gibt bei Erfolg true zurück.

uint  CLBufferRead(
   int           buffer,                    // ein Handle zum Puffer von OpenCL
   uint          buffer_offset,             // ein Offset im OpenCL-Puffer in Bytes
   const matrxi& mat,                       // die Matrix erhält die Werte aus dem Puffer
   ulong         rows=-1,                   // Die Anzahl der Zeilen in der Matrix
   ulong         cols=-1                    // Die Anzahl der Spalten in der Matrix
   );

Einlesen des OpenCL-Puffers in den Vektor und Rückgabe von true bei Erfolg.

uint  CLBufferRead(
   int           buffer,                    // ein Handle zum Puffer von OpenCL
   uint          buffer_offset,             // ein Offset im OpenCL-Puffer in Bytes
   const vector& vec,                       // der Vektor erhält die Werte aus dem Puffer
   ulong         size-1,                    // Länge des Vektors 
   );

Parameter

buffer

[in]  Handle auf den OpenCL-Puffer.

data[]

[in]  Array, um die Werte aus dem OpenCL-Puffer zu empfangen. Wird als Referenz übergeben.

buffer_offset

[in]  Offset im OpenCL-Puffer, mit dem Lesung beginnt, in Bytes. Standardmäßig startet die Lesung am Anfang des Puffers.

data_offset

[in]  Der Index des ersten Elements des Arrays, um Werte des OpenCL-Puffers zu schreiben. Standardmäßig startet die Schreibung von gelesenen Werten in ein Array mit dem Null-Index.

data_count

[in]  Die Anzahl der Werte zu lesen. Standardmäßig wird der gesamte OpenCL-Puffer gelesen.

mat

[out]  Die Matrix zum Lesen von Daten aus dem Puffer kann einer der drei Typen sein: matrix, matrixf oder matrixc.

vec

[out]  Der Vektor zum Lesen von Daten aus dem Puffer kann von einem der drei Typen sein: vector, vectorf oder vectorc.

rows=-1

[in] Wenn der Parameter angegeben wird, sollte auch der Parameter cols (Spalten) angegeben werden. Wenn die neuen Matrixdimensionen nicht angegeben werden, werden die aktuellen verwendet. Ist der Wert -1, so ändert sich die Anzahl der Zeilen nicht.

cols=-1

[in] Wenn der Parameter nicht angegeben wird, sollte auch der Parameter rows (Zeilen) übersprungen werden. Die Matrix hält sich an die Regel: entweder sind beide Parameter angegeben, oder keiner, sonst tritt ein Fehler auf. Werden beide Parameter (rows und cols) angegeben, wird die Größe der Matrix geändert.  Im Falle von -1 ändert sich die Anzahl der Spalten nicht.

size=-1

[in] Wird der Parameter nicht angegeben oder ist sein Wert -1, ändert sich die Vektorlänge nicht.

Rückgabewert

Anzahl der gelesenen Elemente. Im Falle eines Fehlers wird 0 zurückgegeben. Um Informationen über den Fehler zu erhalten, rufen Sie die Funktion GetLastError().

true, wenn eine Matrix oder ein Vektor erfolgreich verarbeitet wurde, ansonsten false.

Hinweis

Für eindimensionale Arrays, wird die Nummer des Elements, in das Schreiben von Daten aus dem OpenCL-Puffer beginnt, unter Berücksichtigung der Flagge AS_SERIES ausgerechnet.

Ein Array von zwei oder mehr Dimensionen wird als eindimensional dargestellt. In diesem Fall ist data_Offset die Anzahl der Elemente, die in der Darstellung angegeben werden soll, nicht die Anzahl der Elemente in der ersten Dimension.

Beispiel zur Berechnung von Pi anhand der Gleichung:

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-Programmcode
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";
//+------------------------------------------------------------------+
//| Skript Programm Start Funktion                                   |
//+------------------------------------------------------------------+
int OnStart()
 {
  Print("Pi-Berechnung: step = "+D2S(_step12)+"; _intrnCnt = "+I2S(_intrnCnt));
//--- Vorbereitung der OpenCL-Kontexte
  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};
//--- Starten des OpenCL-Programms
  ulong start=GetMicrosecondCount();
  if(!CLExecute(clKrn1offsworks))
   {
    Print("CLExecute(clKrn, 1, offs, works) failed! Fehlernummer "GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    return(-1);
   }
//--- Abrufen der Ergebnisse vom OpenCL-Gerät
  vector buffer(_divisor);
  if(!CLBufferRead(clMem0buffer))
   {
    Print("CLBufferRead(clMem, 0, buffer) failed! Fehlernummer "GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    return(-1);
   }
//--- Summe aller Werte zur Berechnung von Pi
  double Pi=buffer.Sum()*_step;
 
  double time=(GetMicrosecondCount()-start)/1000.;
  Print("OpenCL: Pi calculated for "+D2S(time2)+" ms");
  Print("Pi = "+DoubleToString(Pi12));
//--- Freigeben des Speichers
  CLFreeAll(clMemclKrnclPrgclCtx);
//--- Gelungen
  return(0);
 }
  /*
  Pi Calculationstep = 0.000000001000_intrnCnt = 25000
  OpenCLGPU device 'Ellesmereselected
  OpenCLPi calculated for 99.98 ms
  Pi = 3.141592653590
  */ 
//+------------------------------------------------------------------+
//| Hilfsroutine zur Freigabe des Speichers                          |
//+------------------------------------------------------------------+
void CLFreeAll(const int clMemconst int clKrnconst int clPrgconst int clCtx)
 {
  CLBufferFree(clMem);
  CLKernelFree(clKrn);
  CLProgramFree(clPrg);
  CLContextFree(clCtx);
 }