check transfer  0.1
Check data transfer for SDAccell OpenCL application
tf_checktransferin.cpp
Go to the documentation of this file.
1 
2 #include <stdio.h>
3 #include "exceptinfo.h"
4 #include "tf_checktransferin.h"
5 
6 #include "table_engine.h"
7 
8 #include "utypes.h"
9 #include "ipc.h"
10 
11 #include "tf_device.h"
12 #include "parse_cmd.h"
13 #include <vector>
14 
15 
16 //!< Internal data for TF_CheckTransferIn
18 
19  cl_uint RowNumber; //!< Number of first row in the table
20  cl_uint BlockWr; //!< Count of written blocks
21  cl_uint BlockRd; //!< Count of read blocks
22  cl_uint BlockOk; //!< Count of correct blocks
23  cl_uint BlockError; //!< Count of incorrect blocks
24  cl_uint sizeBlock; //!< Size of block [bytes]
25  cl_int sizeOfuint16; //!< Size of block in 512-bit words
26  cl_uint Sig; //!< Signature for status buffer
27  float VelocityCurrent; //!< current speed (on 4 secund interval)
28  float VelocityAverage; //!< average speed (from test start)
29 
30  float VelocityCurMax; //!< maximum of VelocityCurrent
31  float VelocityCurMin; //!< minimum of VelocityCurrent
32 
33  cl_uint metricMode; //!< 0 - binary: 1MB=2^10 bytes, 1 - decimal: 1MB=10^6 bytes
34  cl_uint mbSize; //!< bytes count in 1MB
35 
36  clock_t startTick; //!< Number of start clock();
37  clock_t lastTick; //!< Number of last clock()
38  cl_uint lastBlock; //!< Number BlockWr for lastTick
39  float testTime; //!< Time from test start
40 
41 
42  time_t startTime; //!< time of start main test cycle
43  time_t lastTime; //!< time of last interval
44 
45  cl_ulong dataOut; //!< current data for output
46  cl_ulong dataExpect; //!< expect data from input
47 
48 
49  char *kernelName; //!< kernel name
50 
51  TF_Device *pDevice; //!< OpenCL device and program
52 
53  cl::Kernel krnl_calculate; //!< OpenCL kernel for calculate
54 
55  cl::CommandQueue *q0; //!< Pointer to OpenCL command queue
56  cl::CommandQueue *q1; //!< Pointer to OpenCL command queue
57 
58  std::string deviceName; //!< OpenCL device name
59 
60  cl_uint *pBufOut[2]; //!< pointers to buffers in the host memory
61 
62  cl::Buffer *pBuffer[2]; //!< pointers to buffers in the device memory
63 
64  cl::Buffer *dpStatus; //!< pointer to status buffer in the device memory
65 
66  cl_uint *pStatus; //!< pointer to status buffer in the host memory
67 
68  cl_ulong flagGetStatus; //!< 1 - request for get status information
69 
70  cl_ulong8 arrayExpect; //!< expect values for data block
71 
73  {
74  BlockWr=0;
75  BlockRd=0;
76  BlockOk=0;
77  BlockError=0;
78  RowNumber=0;
79 
80  lastBlock = 0;
81  testTime = 0;
82 
83  dataOut=dataExpect=0xA0000000;
84 
85 
86  kernelName = "gen_cnt";
87 
88 
89  pBufOut[0]=NULL;
90  pBufOut[1]=NULL;
91 
92  pBuffer[0]=NULL;
93  pBuffer[1]=NULL;
94 
95  pStatus = NULL;
96  dpStatus = NULL;
97 
98  q0=NULL;
99  q1=NULL;
100 
101  flagGetStatus=0;
102  VelocityCurMax=0;
103  VelocityCurMin=0;
104  VelocityAverage=0;
105  VelocityCurrent=0;
106 
107  sizeOfuint16=0;
108  };
109 
111  {
112  }
113 
114 
115 };
116 
117 //! Constructor
118 /**
119  *
120  *
121  * \param argc Number of arguments
122  * \parma argv Pointer of argumnts
123  *
124  *
125  * arguments of command line:
126  *
127  * -size <n> : size block of kilobytes, default 64
128  * -metric <n> : 0 - binary: 1MB=2^10=1024*1024=1048576 bytes,
129  * 1 - decimal: 1MB=10^6=1000*1000=1000000 bytes,
130  * default 0
131  *
132  */
133 TF_CheckTransferIn::TF_CheckTransferIn( TableEngine *pTable, TF_Device *pDevice, int argc, char **argv) : TF_TestThread( pTable, argc, argv )
134 {
136 
137  td->sizeBlock = 1024 * GetFromCommnadLine( argc, argv, "-size", 64 );
138 
139  td->metricMode = GetFromCommnadLine( argc, argv, "-metric", 0 );
140  if( 0==td->metricMode )
141  td->mbSize = 1024*1024;
142  else
143  td->mbSize = 1000000;
144 
145  td->pDevice = pDevice;
146 
147 }
148 
149 //! Destructor
151 {
152 
153  free( td->pBufOut[0] ); td->pBufOut[0]=NULL;
154  free( td->pBufOut[1] ); td->pBufOut[1]=NULL;
155  free( td->pStatus ); td->pStatus=NULL;
156 
157 
158  delete td->pBuffer[0]; td->pBuffer[0]=NULL;
159  delete td->pBuffer[1]; td->pBuffer[1]=NULL;
160  delete td->dpStatus; td->dpStatus=NULL;
161 
162 
163  delete td; td=NULL;
164 }
165 
166 //! Prepare test
167 /**
168  * This function executed before main body of test.
169  *
170  *
171  */
173 {
174  printf( "\n");
175  printf( "TF_CheckTransferIn::%s\n\n", __FUNCTION__ );
176 
177 
178  cl::Kernel krnl_calculate( td->pDevice->program, "gen_cnt" );
179  td->krnl_calculate = krnl_calculate;
180 
181 
182  td->sizeOfuint16 = td->sizeBlock/64; // count of words by 512 bits
183 
184 
185  printf( "Alloc host memory 2 x %d ", td->sizeBlock );
186  {
187  void *ptr=(void*)0xAAAA;
188  int err;
189  err = posix_memalign( &ptr, 4096, td->sizeBlock );
190  if( err )
191  throw except_info( "%s - memory allocation error ", __FUNCTION__);
192  td->pBufOut[0] = (cl_uint*) ptr;
193  //printf( "ptr=%p\n", ptr );
194 
195  err = posix_memalign( &ptr, 4096, td->sizeBlock );
196  if( err )
197  throw except_info( "%s - memory allocation error ", __FUNCTION__);
198  td->pBufOut[1] = (cl_uint*) ptr;
199 
200  //printf( "ptr=%p\n", ptr );
201 
202 
203 
204  err = posix_memalign( &ptr, 4096, 16384 );
205  if( err )
206  throw except_info( "%s - memory allocation error ", __FUNCTION__);
207  td->pStatus = (cl_uint*) ptr;
208 
209 
210  }
211  printf( " - Ok\n" );
212 
213  printf( "Alloc device memory 2 x %d (DDR0 & DDR1) ", td->sizeBlock );
214  {
215  cl::Buffer *pBuf;
216 
217  cl_mem_ext_ptr_t input_buffer_ext;
218 
219  input_buffer_ext.flags = XCL_MEM_DDR_BANK0;
220  input_buffer_ext.obj = NULL;
221  input_buffer_ext.param = 0;
222 
223  pBuf = new cl::Buffer( td->pDevice->context,
224  CL_MEM_READ_WRITE | CL_MEM_EXT_PTR_XILINX,
225  td->sizeBlock,
226  &input_buffer_ext
227  );
228  td->pBuffer[0] = pBuf;
229  }
230 
231  {
232  cl::Buffer *pBuf;
233 
234  cl_mem_ext_ptr_t input_buffer_ext;
235 
236  input_buffer_ext.flags = XCL_MEM_DDR_BANK0;
237  input_buffer_ext.obj = NULL;
238  input_buffer_ext.param = 0;
239 
240  pBuf = new cl::Buffer( td->pDevice->context,
241  CL_MEM_READ_WRITE | CL_MEM_EXT_PTR_XILINX,
242  td->sizeBlock,
243  &input_buffer_ext
244  );
245  td->pBuffer[1] = pBuf;
246  }
247 
248  {
249  cl::Buffer *pBuf;
250 
251  cl_mem_ext_ptr_t input_buffer_ext;
252 
253  input_buffer_ext.flags = XCL_MEM_DDR_BANK0;
254  input_buffer_ext.obj = NULL;
255  input_buffer_ext.param = 0;
256 
257  pBuf = new cl::Buffer( td->pDevice->context,
258  CL_MEM_READ_WRITE | CL_MEM_EXT_PTR_XILINX,
259  16384,
260  &input_buffer_ext
261  );
262  td->dpStatus = pBuf;
263 
264 
265  }
266 
267 
268  {
269  cl_int err0;
270  cl_int err1;
271 
272  cl_command_queue_properties properties0 = CL_QUEUE_PROFILING_ENABLE;
273  cl_command_queue_properties properties1 = CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE;
274 
275  td->q0 = new cl::CommandQueue(td->pDevice->context, td->pDevice->device, properties0, &err0 );
276  td->q1 = new cl::CommandQueue(td->pDevice->context, td->pDevice->device, properties1, &err1 );
277 
278  if( CL_SUCCESS != err0 )
279  throw except_info( "%s - Error for create CommandQueue q0; err=%d ", __FUNCTION__, err0 );
280 
281  if( CL_SUCCESS != err1 )
282  throw except_info( "%s - Error for create CommandQueue q1; err=%d ", __FUNCTION__, err1 );
283 
284  }
285  {
286  for( int ii=0; ii<512; ii++ )
287  {
288  td->pStatus[ii]=0;
289  }
290  td->pStatus[0]=0xBB67;
291 
292  cl_ulong val=td->dataOut;
293  cl_ulong *ptr = (cl_ulong *)&(td->pStatus[16]);
294 
295  // Set initial value
296  for( int ii=0; ii<8; ii++ )
297  {
298  *ptr++ = val++;
299  }
300 
301  // Set add const
302  for( int ii=0; ii<8; ii++ )
303  {
304  *ptr++=8;
305  }
306 
307  cl_int ret=td->q0->enqueueWriteBuffer(
308  *(td->dpStatus),
309  CL_TRUE,
310  0,
311  4096,
312  td->pStatus,
313  NULL,
314  NULL
315  );
316  }
317 
318  printf( " - Ok\n" );
319 
320 }
321 
322 //! Free any resource
324 {
325  printf( "TF_CheckTransferIn::%s\n\n", __FUNCTION__ );
326 
327  delete td->q0; td->q0=NULL;
328  delete td->q1; td->q1=NULL;
329 
330 
331 }
332 
333 //! Show results of test
335 {
336  printf( "\nTF_CheckTransferIn::%s\n\n", __FUNCTION__ );
337  //GetStatus();
338 
339  int flag_error=0;
340 
341  if( 0xAA56==td->Sig )
342  {
343  printf( "Sig=0xAA56 - Ok\n");
344  } else
345  {
346  printf( "Sig=0x%X - Error, expect 0xAA56\n", td->Sig );
347  flag_error=1;
348  }
349  printf( "BlockWr = %d\n", td->BlockWr );
350  printf( "BlockRd = %d\n", td->BlockRd );
351  printf( "BlockOK = %d\n", td->BlockOk );
352  printf( "BlockError = %d\n\n", td->BlockError );
353 
354  printf( "Size of block = %u \n\n", td->sizeBlock);
355 
356  printf( "Test time = %-.0f s\n\n", td->testTime);
357 
358  printf( "VelocityAverage = %10.1f MB/s\n", td->VelocityAverage );
359  printf( "VelocityCurrentMax = %10.1f MB/s\n", td->VelocityCurMax );
360  printf( "VelocityCurrentMin = %10.1f MB/s\n\n", td->VelocityCurMin );
361 
362  if( 0==td->metricMode)
363  printf( " 1 MB = 2^10 = 1024*1024 = 1048576 bytes\n");
364  else
365  printf( " 1 MB = 10^6 = 1000000 bytes\n");
366 
367 
368 
369  if( 0 == td->BlockRd )
370  flag_error++;
371 
372  if( 0 != td->BlockError )
373  flag_error++;
374 
375  if( 0==flag_error )
376  printf( "\nTest finished successfully\n\n" );
377  else
378  printf( "\nTest finished with errors\n\n" );
379 
380 }
381 
382 //! Show table during test executing
384 {
385  m_pTemplateEngine->SetValueTable( td->RowNumber, 1, (unsigned)td->BlockWr, "%10d" );
386  m_pTemplateEngine->SetValueTable( td->RowNumber, 2, (unsigned)td->BlockRd, "%10d" );
387 
388  m_pTemplateEngine->SetValueTable( td->RowNumber, 3, (unsigned)td->BlockOk, "%10d" );
389  m_pTemplateEngine->SetValueTable( td->RowNumber, 4, (unsigned)td->BlockError, "%10d" );
392 
393  m_pTemplateEngine->SetValueTable( td->RowNumber, 0, "IN: %7.1f", td->testTime );
394 
395 
396  td->flagGetStatus=1;
397 }
398 
399 
400 //! Wait for complete data transfer
402 {
403  event.wait();
404 }
405 
406 //! Start data transfer
407 void TF_CheckTransferIn::StartReadBuf( cl::Buffer *pBufDevice, cl_uint *pHost, cl::Event &event )
408 {
409  td->q0->enqueueReadBuffer(
410  *(pBufDevice),
411  CL_FALSE,
412  0,
413  td->sizeBlock,
414  pHost,
415  NULL,
416  &event
417  );
418 
419  td->BlockRd++;
420 }
421 
422 //! Start kernel for buffer
423 void TF_CheckTransferIn::StartCalculateBuf( cl::Buffer *pBufDevice, cl::Event &event )
424 {
425 
426  cl::NDRange globalNDR(1,1,1);
427  cl::NDRange localNDR(1,1,1);
428  cl::NDRange offsetNDR=cl::NullRange;
429 
430  td->krnl_calculate.setArg( 0, *pBufDevice );
431  td->krnl_calculate.setArg( 1, *(td->dpStatus) );
432  td->krnl_calculate.setArg( 2, td->sizeOfuint16 );
433 
434  td->q1->enqueueNDRangeKernel(
436  offsetNDR,
437  globalNDR,
438  localNDR,
439  NULL, //&events0,
440  &event //&eventCompletionExecuting0
441 
442  );
443 
444 }
445 
446 //! Wait for complete calculate
448 {
449  event.wait();
450 }
451 
452 
453 //! Main body of test
455 {
457 
458 
459  cl::Event eventCompletionTransfer0;
460  cl::Event eventCompletionTransfer1;
461  cl::Event eventCompletionExecuting0;
462  cl::Event eventCompletionExecuting1;
463  cl_int ret;
464 
465  std::vector<cl::Event> events0;
466  std::vector<cl::Event> events1;
467 
468  int flag_continue=0;
469  int flag_first_velocity=1;
470 
471 
472 
473  td->lastTime = td->startTime = time(NULL);
474 
475  // start check buffer 0 on device - quick time
476  StartCalculateBuf( td->pBuffer[0], eventCompletionExecuting0 );
477 
478 
479  for( ; ; )
480  {
481  if( this->m_isTerminate )
482  break;
483 
484 
485  if( td->flagGetStatus )
486  {
487  GetStatus();
488  td->flagGetStatus=0;
489  }
490 
491  // Main body
492 
493  WaitForCalculateComplete( eventCompletionExecuting0 );
494 
495  // start data transfer from buffer 0 on device - quick time
496  StartReadBuf( td->pBuffer[0], td->pBufOut[0], eventCompletionTransfer0 );
497 
498  // start check buffer 1 on device - quick time
499  StartCalculateBuf( td->pBuffer[1], eventCompletionExecuting1 );
500 
501  if( flag_continue )
502  {
503  // check buffer 0 - long time operation
504  CheckBuffer( td->pBufOut[1] );
505  }
506 
507  // wait complete transfer 0 - first wait
508  WaitForTransferBufComplete( eventCompletionTransfer0 );
509 
510  WaitForCalculateComplete( eventCompletionExecuting1 );
511 
512  // start data transfer from buffer 1 on device - quick time
513  StartReadBuf( td->pBuffer[1], td->pBufOut[1], eventCompletionTransfer1 );
514 
515  // start check buffer 0 on device - quick time
516  StartCalculateBuf( td->pBuffer[0], eventCompletionExecuting0 );
517 
518  // check buffer 0 - long time operation
519  CheckBuffer( td->pBufOut[0] );
520 
521  // wait complete transfer 1 - first wait
522  WaitForTransferBufComplete( eventCompletionTransfer1 );
523 
524 
525  flag_continue=1;
526 
527 
528  time_t currentTime = time(NULL);
529  time_t timeFromStart = currentTime - td->startTime;
530  time_t diff = currentTime - td->lastTime;
531  td->testTime = timeFromStart;
532 
533  if( diff >= 4 )
534  {
535  double velocity = (1.0L*(td->BlockRd-td->lastBlock)*td->sizeBlock)/diff;
536 
537  td->VelocityCurrent = velocity / (td->mbSize);
538 
539 
540  velocity = 1.0L*(td->BlockRd)*td->sizeBlock/timeFromStart;
541 
542  td->VelocityAverage = velocity / (td->mbSize);
543 
544  td->lastTime = currentTime;
545  td->lastBlock = td->BlockRd;
546 
547  if( 1==flag_first_velocity )
548  {
551  flag_first_velocity=0;
552  } else
553  {
556 
559 
560  }
561  }
562  }
563 
564  GetStatus();
565 
566 }
567 
568 //! set test data in buffer
569 void TF_CheckTransferIn::SetBuffer( cl_uint *ptr )
570 {
571  cl_ulong *dst = (cl_ulong*) ptr;
572  cl_uint count = td->sizeBlock / sizeof(cl_ulong) / 16;
573  cl_ulong val=td->dataOut;
574  for( cl_uint ii=0; ii<count; ii++ )
575  {
576  *dst++=val++;
577  *dst++=val++;
578  *dst++=val++;
579  *dst++=val++;
580  *dst++=val++;
581  *dst++=val++;
582  *dst++=val++;
583  *dst++=val++;
584  *dst++=val++;
585  *dst++=val++;
586  *dst++=val++;
587  *dst++=val++;
588  *dst++=val++;
589  *dst++=val++;
590  *dst++=val++;
591  *dst++=val++;
592  }
593  td->dataOut=val;
594 }
595 
596 //! check data in the buffer
598 {
599  cl_ulong *src = (cl_ulong*)ptr;
600  cl_uint count = td->sizeBlock / sizeof(cl_ulong);
601  cl_ulong val=td->dataExpect;
602  cl_ulong di;
603  cl_ulong flag_error=0;
604  for( int ii=0; ii<count; ii++ )
605  {
606  di = *src++;
607 
608  if( di!=val )
609  {
610  flag_error++;
611  }
612  val++;
613  }
614  td->dataExpect=val;
615 
616  if( 0==flag_error )
617  td->BlockOk++;
618  else
619  td->BlockError++;
620 }
621 
622 //! Read status information from device
624 {
625  if( NULL==td->pStatus )
626  return;
627 
628 
629  cl_int ret=td->q0->enqueueReadBuffer(
630  *(td->dpStatus),
631  CL_TRUE,
632  0,
633  512,
634  td->pStatus,
635  NULL,
636  NULL
637  );
638 
639  td->Sig = td->pStatus[0];
640  td->BlockWr = td->pStatus[1];
641 
642 }
cl::CommandQueue * q1
Pointer to OpenCL command queue.
cl_ulong flagGetStatus
1 - request for get status information
cl_uint BlockRd
Count of read blocks.
< Internal data for TF_CheckTransferIn
cl::Program program
OpenCL program.
Definition: tf_device.h:28
TF_Device * pDevice
OpenCL device and program.
void StartCalculateBuf(cl::Buffer *pDevice, cl::Event &event)
Start kernel for buffer.
cl_ulong dataExpect
expect data from input
time_t lastTime
time of last interval
virtual void PrepareInThread()
Prepare test.
cl::Buffer * pBuffer[2]
pointers to buffers in the device memory
void SetBuffer(cl_uint *ptr)
set test data in buffer buffer
cl_ulong8 arrayExpect
expect values for data block
cl_uint BlockOk
Count of correct blocks.
cl::CommandQueue * q0
Pointer to OpenCL command queue.
TF_CheckTransferIn_task_data * td
< Internal data for TF_CheckTransferIn
float VelocityCurMax
maximum of VelocityCurrent
except_info_t except_info(const char *fmt,...)
Definition: exceptinfo.cpp:25
cl::Buffer * dpStatus
pointer to status buffer in the device memory
cl_int sizeOfuint16
Size of block in 512-bit words.
TableEngine * m_pTemplateEngine
Definition: tf_test.h:21
virtual void Run()
Main body of test.
~TF_CheckTransferIn()
Destructor.
cl_uint sizeBlock
Size of block [bytes].
clock_t startTick
Number of start clock();.
cl_uint mbSize
bytes count in 1MB
cl_uint RowNumber
Number of first row in the table.
void CheckBuffer(cl_uint *ptr)
check data in the buffer
void GetStatus(void)
Read status information from device.
cl_uint BlockWr
Count of written blocks.
Base class for application with thread.
Definition: tf_testthread.h:23
virtual void GetResultInThread()
Show results of test.
void WaitForCalculateComplete(cl::Event &event)
Wait for complete calculate.
cl_uint * pBufOut[2]
pointers to buffers in the host memory
virtual void StepTable()
Show table during test executing.
cl_ulong dataOut
current data for output
cl_uint * pStatus
pointer to status buffer in the host memory
void StartReadBuf(cl::Buffer *pDevice, cl_uint *pHost, cl::Event &event)
Start data transfer.
cl::Kernel krnl_calculate
OpenCL kernel for calculate.
virtual int AddRowTable()=0
float VelocityCurrent
current speed (on 4 secund interval)
cl::Context context
OpenCL context.
Definition: tf_device.h:27
virtual void CleanupInThread()
Free any resource.
cl_uint lastBlock
Number BlockWr for lastTick.
int GetFromCommnadLine(int argc, char **argv, const char *name, int defValue)
Get integer value from command line.
Definition: parse_cmd.cpp:29
cl_uint metricMode
0 - binary: 1MB=2^10 bytes, 1 - decimal: 1MB=10^6 bytes
virtual int SetValueTable(unsigned nRow, unsigned nColumn, const char *fmt,...)=0
common data for OpenCL device
Definition: tf_device.h:17
float VelocityCurMin
minimum of VelocityCurrent
TF_CheckTransferIn(TableEngine *pTable, TF_Device *pDevice, int argc, char **argv)
Constructor.
cl_uint BlockError
Count of incorrect blocks.
cl::Device device
OpenCL device.
Definition: tf_device.h:26
clock_t lastTick
Number of last clock()
float VelocityAverage
average speed (from test start)
time_t startTime
time of start main test cycle
void WaitForTransferBufComplete(cl::Event &event)
Wait for complete data transfer.
std::string deviceName
OpenCL device name.
cl_uint Sig
Signature for status buffer.
float testTime
Time from test start.