CLBufferRead

Bir OpenCL tamponunu bir diziye okur ve okunan eleman sayısına dönüş yapar.

uint  CLBufferRead(
   int          buffer,                    // OpenCL tamponunun tanıtıcı değeri
   const void&  data[],                    // değerler için dizi
   uint         buffer_offset=0,           // OpenCL tamponunda bayt bazında konum değeri, varsayılan olarak 0
   uint         data_offset=0,             // Eleman sayısı bazında konum değeri, varsayılan olarak 0
   uint         data_count=WHOLE_ARRAY     // Tampondaki okunacak verilerin sayısı, varsayılan olarak bütün tampon
   );

Matrisleri ve vektörleri işlemek için versiyonlar da mevcuttur.

OpenCL arabelleğini matrise okur ve başarılı olursa true değerini geri döndürür.

uint  CLBufferRead(
   int           buffer,                    // OpenCL arabelleğine olan tanıtıcı
   uint          buffer_offset,             // OpenCL arabelleğinde bayt cinsinden ofset
   const matrxi& mat,                       // arabellekten değerler alacak matris
   ulong         rows=-1,                   // matristeki satır sayısı
   ulong         cols=-1                    // matristeki sütun sayısı
   );

OpenCL arabelleğini vektöre okur ve başarılı olursa true değerini geri döndürür.

uint  CLBufferRead(
   int           buffer,                    // OpenCL arabelleğine olan tanıtıcı
   uint          buffer_offset,             // OpenCL arabelleğinde bayt cinsinden ofset
   const vector& vec,                       // arabellekten değerler alacak vektör
   ulong         size-1,                    // vektör uzunluğu
   );

Parametreler

buffer

[in]  OpenCL tamponu için bir tanıtıcı değer.

data[]

[in]  OpenCL tamponunun değerlerini almak için bir dizi. Referans ile geçirilir.

buffer_offset

[in]  OpenCL tamponunda okuma işleminin başlayacağı bayt bazındaki konum değeri. Okuma, varsayılan olarak tamponun en başından başlar.

data_offset

[in]  OpenCL tamponunun değerlerini yazmak için, ilk dizi elemanının indisi. Okunan elemanların yazımına, varsayılan olarak sıfırdan başlanır.

data_count

[in]  Okunması gereken değerlerin sayısı. Varsayılan olarak OpenCL tamponunun tamamı okunur.

mat

[out]  Arabellekten veriler alacak matris şu üç türden herhangi biri olabilir: matrix, matrixf veya matrixc.

vec

[out]  Arabellekten veriler alacak vektör şu üç türden herhangi biri olabilir: vector, vectorf veya vectorc.

rows=-1

[in]  Bu parametre belirtilirse, cols parametresi de belirtilmelidir. Yeni matris boyutları belirtilmezse, mevcut olanlar kullanılır. Değer -1 olarak belirtilirse satır sayısı değişmez.

cols=-1

[in]  Bu parametre belirtilmezse, rows parametresi de belirtilmemelidir. Matris şu kurala bağlıdır: ya her iki parametre de belirtilir ya da hiçbiri belirtilmez, aksi takdirde hata meydana gelir. Her iki parametre de (rows ve cols) belirtilirse, matris boyutu değiştirilir. Değer -1 olarak belirtilirse sütun sayısı değişmez.

size=-1

[in]  Bu parametre belirtilmezse veya -1 olarak belirtilirse vektör uzunluğu değişmez.

Dönüş değeri

Okunan elemanların sayısı. Hata durumunda 0 dönüşü yapılır. Hata hakkında bilgi almak için GetLastError() fonksiyonunu kullanın.

Matris veya vektör başarıyla işlenirse true, aksi takdirde false geri döndürür.

Not

Tek boyutlu diziler için, OpenCL tamponuna yazılacak elemanların sayısı, AS_SERIES bayrağı hesaba katılarak hesaplanır.

İki veya daha fazla boyuta sahip diziler, tek boyutlu farz edilir. Bu durumda, data_offset parametresi, ilk boyuttaki elemanların sayısı değil, sunulan dizide atlanması gereken elemanların sayısıdır.

Denklem kullanılarak pi sayısının hesaplamasına örnek:

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 programı kodu
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";
 
//+------------------------------------------------------------------+
//| Komut dosyası başlatma fonksiyonu                                |
//+------------------------------------------------------------------+
int OnStart()
 {
  Print("Pi sayısının hesaplanması: adım = "+D2S(_step12)+"; _intrnCnt = "+I2S(_intrnCnt));
//--- OpenCL içeriklerini hazırla
  int clCtx;
  if((clCtx=CLContextCreate(CL_USE_GPU_ONLY))==INVALID_HANDLE)
   {
    Print("OpenCL bulunamadı");
    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 programını başlat
  ulong start=GetMicrosecondCount();
  if(!CLExecute(clKrn1offsworks))
   {
    Print("CLExecute(clKrn, 1, offs, works) başarısız oldu! Hata ",GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    return(-1);
   }
//--- OpenCL cihazından sonuçları al
  vector buffer(_divisor);
  if(!CLBufferRead(clMem0buffer))
   {
    Print("CLBufferRead(clMem, 0, buffer) başarısız oldu! Hata ",GetLastError());
    CLFreeAll(clMemclKrnclPrgclCtx);
    return(-1);
   }
//--- tüm değerleri pi sayısını hesaplamak için topla
  double Pi=buffer.Sum()*_step;
 
  double time=(GetMicrosecondCount()-start)/1000.;
  Print("OpenCL: pi sayısı hesaplandı, geçen süre:"+D2S(time2)+" ms");
  Print("Pi sayısı = "+DoubleToString(Pi12));
//--- hafızayı temizle
  CLFreeAll(clMemclKrnclPrgclCtx);
//--- başarılı
  return(0);
 }
  /*
  Pi sayısının hesaplanmasıadım = 0.000000001000_intrnCnt = 25000
  OpenCLGPU device 'Ellesmereselected
  OpenCLpi sayısı hesaplandıgeçen süre: 99.98 ms
  Pi sayısı = 3.141592653590
  */ 
//+------------------------------------------------------------------+
//| Hafızayı temizlemek için yardımcı kod parçası                    |
//+------------------------------------------------------------------+
void CLFreeAll(const int clMemconst int clKrnconst int clPrgconst int clCtx)
 {
  CLBufferFree(clMem);
  CLKernelFree(clKrn);
  CLProgramFree(clPrg);
  CLContextFree(clCtx);
 }