cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
mceuropeanengine.cpp
Go to the documentation of this file.
1 
17 
36 #include "../../../../../HOST/quantitative_finance/mceuropeanengine/languages/cplusplus/include/config.h"
37 #include "../include/mceuropeanengine.hpp"
38 
39 #if defined USE_HLSLIB_DATAFLOW || defined USE_HLSLIB_STREAM
40 #include "../../../../../hlslib/include/hlslib/xilinx/Stream.h"
41 #include "../../../../../hlslib/include/hlslib/xilinx/Simulation.h"
42 #endif
43 
44 #ifdef USE_HLSLIB_STREAM
45 using hlslib::Stream;
46 #endif
47 using hls::stream;
48 
52 
53 
54 
59  NetworkWord word,
60  varin *instruct,
61  unsigned int *processed_word_rx,
62  unsigned int *struct_loaded)
63 {
64  //#pragma HLS INLINE
65  const unsigned int loop_cnt = (BITS_PER_10GBITETHRNET_AXI_PACKET/INPUT_PTR_WIDTH);
66  for (unsigned int i=0; i<loop_cnt; i++) {
67  printf("DEBUG: Checking: word.tkeep=%u >> %u = %u\n", word.tkeep.to_int(), i, (word.tkeep.to_int() >> i));
68  if ((word.tkeep >> i) == 0) {
69  printf("WARNING: value with tkeep=0 at i=%u\n", i);
70  continue;
71  }
72  intToFloatUnion intToFloat;
73  intToFloat.i = (DtUsedInt)(word.tdata >> i*loop_cnt);
74  switch((*processed_word_rx)++)
75  {
76  case 0:
77  if ((intToFloat.i == 0) || (intToFloat.i > OUTDEP)) {
78  printf("WARNING Invalid instruct->loop_nm = %u. Will assign %u\n", (unsigned int)intToFloat.i, OUTDEP);
79  instruct->loop_nm = OUTDEP;
80  }
81  else {
82  instruct->loop_nm = intToFloat.i;
83  }
84  printf("DEBUG instruct->loop_nm = %u\n", (unsigned int)instruct->loop_nm);
85  break;
86  case 1:
87  instruct->seed = intToFloat.i;
88  printf("DEBUG instruct->seed = %u\n", (unsigned int)instruct->seed);
89  break;
90  case 2:
91  instruct->underlying = intToFloat.f;
92  printf("DEBUG instruct->underlying = %f\n", instruct->underlying);
93  break;
94  case 3:
95  instruct->volatility = intToFloat.f;
96  printf("DEBUG instruct->volatility = %f\n", instruct->volatility);
97  break;
98  case 4:
99  instruct->dividendYield = intToFloat.f;
100  printf("DEBUG instruct->dividendYield = %f\n", instruct->dividendYield);
101  break;
102  case 5:
103  instruct->riskFreeRate = intToFloat.f;
104  printf("DEBUG instruct->riskFreeRate = %f\n", instruct->riskFreeRate);
105  break;
106  case 6:
107  instruct->timeLength = intToFloat.f;
108  printf("DEBUG instruct->timeLength = %f\n", instruct->timeLength);
109  break;
110  case 7:
111  instruct->strike = intToFloat.f;
112  printf("DEBUG instruct->strike = %f\n", instruct->strike);
113  break;
114  case 8:
115  instruct->optionType = intToFloat.i;
116  printf("DEBUG instruct->optionType = %u\n", (unsigned int)instruct->optionType);
117  break;
118  case 9:
119  instruct->requiredTolerance = intToFloat.f;
120  printf("DEBUG instruct->requiredTolerance = %f\n", instruct->requiredTolerance);
121  break;
122  case 10:
123  instruct->requiredSamples = intToFloat.i;
124  printf("DEBUG instruct->requiredSamples = %u\n", (unsigned int)instruct->requiredSamples);
125  break;
126  case 11:
127  instruct->timeSteps = intToFloat.i;
128  printf("DEBUG instruct->timeSteps = %u\n", (unsigned int)instruct->timeSteps);
129  break;
130  case 12:
131  instruct->maxSamples = intToFloat.i;
132  printf("DEBUG instruct->maxSamples = %u\n", (unsigned int)instruct->maxSamples);
133  *struct_loaded = 1;
134  printf("DEBUG in storeWordToStruct: WARNING - you've loaded the struct. Will put *struct_loaded = 1.\n");
135  break;
136  default:
137  break;
138  }
139  }
140 
141 }
142 
143 
144 
145 
158 void pRXPath(
159  stream<NetworkWord> &siSHL_This_Data,
160  stream<NetworkMetaStream> &siNrc_meta,
161  varin *instruct,
162  NetworkMetaStream meta_tmp,
163  unsigned int *processed_word_rx,
164  unsigned int *struct_loaded
165  )
166 {
167  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
168  //#pragma HLS DATAFLOW interval=1
169  #pragma HLS INLINE
170  //-- LOCAL VARIABLES ------------------------------------------------------
171  NetworkWord netWord;
172 
173  switch(enqueueFSM)
174  {
175  case WAIT_FOR_META:
176  printf("DEBUG in pRXPath: enqueueFSM - WAIT_FOR_META, *processed_word_rx=%u\n",
177  *processed_word_rx);
178  if ( !siNrc_meta.empty())
179  {
180  meta_tmp = siNrc_meta.read();
181  meta_tmp.tlast = 1; //just to be sure...
183  }
184  break;
185 
186  case PROCESSING_PACKET:
187  printf("DEBUG in pRXPath: enqueueFSM - PROCESSING_PACKET, *processed_word_rx=%u\n",
188  *processed_word_rx);
189  if ( !siSHL_This_Data.empty() )
190  {
191  //-- Read incoming data chunk
192  netWord = siSHL_This_Data.read();
193  storeWordToStruct(netWord, instruct, processed_word_rx, struct_loaded);
194  if(netWord.tlast == 1)
195  {
197  }
198  }
199  break;
200  }
201 
202 
203 }
204 
205 
206 
218  stream<NetworkWord> &sRxpToTxp_Data,
219  stream<NetworkMetaStream> &sRxtoTx_Meta,
220  NetworkMetaStream meta_tmp,
221  varin *instruct,
222  DtUsed *out,
223  unsigned int *processed_word_rx,
224  unsigned int *processed_word_proc,
225  unsigned int *struct_loaded
226  )
227 {
228  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
229  //#pragma HLS DATAFLOW interval=1
230  #pragma HLS INLINE
231  //-- LOCAL VARIABLES ------------------------------------------------------
232  NetworkWord newWord;
233  intToFloatUnion intToFloat;
234  static bool finished = false;
235  #pragma HLS reset variable=finished
236 
237  switch(MCEuropeanEngineFSM)
238  {
239  case WAIT_FOR_META:
240  printf("DEBUG in pProcPath: WAIT_FOR_META\n");
241  *processed_word_proc = 0;
242  finished = false;
243  if ( (*struct_loaded) == 1 )
244  {
246  *processed_word_rx = 0;
247  *struct_loaded = 0;
248  }
249  break;
250 
251  case PROCESSING_PACKET:
252  printf("DEBUG in pProcPath: PROCESSING_PACKET\n");
253  //if ( !img_in_axi_stream.empty() && !img_out_axi_stream.full() )
254  {
255  kernel_mc(instruct->loop_nm,
256  instruct->seed,
257  instruct->underlying,
258  instruct->volatility,
259  instruct->dividendYield,
260  instruct->riskFreeRate, // model parameter
261  instruct->timeLength,
262  instruct->strike,
263  instruct->optionType, // option parameter
264  out,
265  instruct->requiredTolerance,
266  instruct->requiredSamples,
267  instruct->timeSteps,
268  instruct->maxSamples,
269  &finished);
271  }
272  break;
273  case PROCESSING_WAIT:
274  printf("DEBUG in pProcPath: PROCESSING_WAIT\n");
275  {
276  if (finished) {
277  finished = false;
279  }
280  }
281  break;
282 
284  printf("DEBUG in pProcPath: MCEUROPEANENGINE_RETURN_RESULTS, *processed_word_proc=%u\n", *processed_word_proc);
285  if ( !sRxpToTxp_Data.full() && !sRxtoTx_Meta.full()) {
286  if (((((*processed_word_proc)+PACK_SIZE)*sizeof(DtUsed)) % PACK_SIZE == 0)){
287  printf("DEBUG in pProcPath: New packet will be needed. Writting to sRxtoTx_Meta.\n");
288  sRxtoTx_Meta.write(meta_tmp);
289  }
290  bool last;
291  if ( (*processed_word_proc) == instruct->loop_nm-1 ) {
292  last = 1;
294  }
295  else {
296  last = 0;
297  }
298  //TODO: find why Vitis kernel does not set keep and last by itself
299  unsigned int keep = 255;
300  intToFloat.f = out[(*processed_word_proc)++];
301  newWord = NetworkWord((ap_uint<64>)intToFloat.i, keep, last);
302  sRxpToTxp_Data.write(newWord);
303  }
304  break;
305  } // end switch
306 }
307 
308 
309 
310 
322 void pTXPath(
323  stream<NetworkWord> &soTHIS_Shl_Data,
324  stream<NetworkMetaStream> &soNrc_meta,
325  stream<NetworkWord> &sRxpToTxp_Data,
326  stream<NetworkMetaStream> &sRxtoTx_Meta,
327  unsigned int *processed_word_tx,
328  ap_uint<32> *pi_rank,
329  ap_uint<32> *pi_size
330  )
331 {
332  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
333  //#pragma HLS DATAFLOW interval=1
334  #pragma HLS INLINE
335  //-- LOCAL VARIABLES ------------------------------------------------------
336  NetworkWord netWordTx;
337  NetworkMeta meta_in = NetworkMeta();
338  NetworkMetaStream meta_out_stream = NetworkMetaStream();
339 
340  switch(dequeueFSM)
341  {
343  printf("DEBUG in pTXPath: dequeueFSM=%d - WAIT_FOR_STREAM_PAIR, *processed_word_tx=%u\n",
344  dequeueFSM, *processed_word_tx);
345  //-- Forward incoming chunk to SHELL
346  *processed_word_tx = 0;
347 
348  /*
349  printf("!sRxpToTxp_Data.empty()=%d\n", !sRxpToTxp_Data.empty());
350  printf("!sRxtoTx_Meta.empty()=%d\n", !sRxtoTx_Meta.empty());
351  printf("!soTHIS_Shl_Data.full()=%d\n", !soTHIS_Shl_Data.full());
352  printf("!soNrc_meta.full()=%d\n", !soNrc_meta.full());
353  */
354 
355  if (( !sRxpToTxp_Data.empty() && !sRxtoTx_Meta.empty()
356  && !soTHIS_Shl_Data.full() && !soNrc_meta.full() ))
357  {
358  netWordTx = sRxpToTxp_Data.read();
359 
360  // in case MTU=8 ensure tlast is set in WAIT_FOR_STREAM_PAIR and don't visit PROCESSING_PACKET
361  if (PACK_SIZE == 8)
362  {
363  netWordTx.tlast = 1;
364  }
365  soTHIS_Shl_Data.write(netWordTx);
366 
367  meta_in = sRxtoTx_Meta.read().tdata;
368 
369  meta_out_stream.tlast = 1;
370  meta_out_stream.tkeep = 0xFF; //just to be sure
371 
372  meta_out_stream.tdata.dst_rank = (*pi_rank + 1) % *pi_size;
373  //meta_out_stream.tdata.dst_port = DEFAULT_TX_PORT;
374  meta_out_stream.tdata.src_rank = (NodeId) *pi_rank;
375  //meta_out_stream.tdata.src_port = DEFAULT_RX_PORT;
376  //printf("rank: %d; size: %d; \n", (int) *pi_rank, (int) *pi_size);
377  //printf("meat_out.dst_rank: %d\n", (int) meta_out_stream.tdata.dst_rank);
378  meta_out_stream.tdata.dst_port = meta_in.src_port;
379  meta_out_stream.tdata.src_port = meta_in.dst_port;
380 
381  soNrc_meta.write(meta_out_stream);
382 
383  (*processed_word_tx)++;
384 
385  if(netWordTx.tlast != 1)
386  {
388  }
389  }
390  break;
391 
392  case PROCESSING_PACKET:
393  printf("DEBUG in pTXPath: dequeueFSM=%d - PROCESSING_PACKET, *processed_word_tx=%u\n",
394  dequeueFSM, *processed_word_tx);
395  if( !sRxpToTxp_Data.empty() && !soTHIS_Shl_Data.full())
396  {
397  netWordTx = sRxpToTxp_Data.read();
398  (*processed_word_tx)++;
399 
400  // This is a normal termination of the axi stream from vitis functions
401  if(netWordTx.tlast == 1)
402  {
404  }
405  else if (((*processed_word_tx)*sizeof(DtUsed)) % PACK_SIZE == 0)
406  // This is our own termination based on the custom MTU we have set in PACK_SIZE.
407  // TODO: We can map PACK_SIZE to a dynamically assigned value either through MMIO or header
408  // in order to have a functional bitstream for any MTU size
409  {
410  netWordTx.tlast = 1;
412  }
413  soTHIS_Shl_Data.write(netWordTx);
414  }
415  break;
416  }
417 }
418 
419 
420 
427 
428  ap_uint<32> *pi_rank,
429  ap_uint<32> *pi_size,
430  //------------------------------------------------------
431  //-- SHELL / This / Udp/TCP Interfaces
432  //------------------------------------------------------
433  stream<NetworkWord> &siSHL_This_Data,
434  stream<NetworkWord> &soTHIS_Shl_Data,
435  stream<NetworkMetaStream> &siNrc_meta,
436  stream<NetworkMetaStream> &soNrc_meta,
437  ap_uint<32> *po_rx_ports
438  )
439 {
440 
441  //-- DIRECTIVES FOR THE BLOCK ---------------------------------------------
442  //#pragma HLS INTERFACE ap_ctrl_none port=return
443 
444  //#pragma HLS INTERFACE ap_stable port=piSHL_This_MmioEchoCtrl
445 
446 #pragma HLS INTERFACE axis register both port=siSHL_This_Data
447 #pragma HLS INTERFACE axis register both port=soTHIS_Shl_Data
448 
449 #pragma HLS INTERFACE axis register both port=siNrc_meta
450 #pragma HLS INTERFACE axis register both port=soNrc_meta
451 
452 #pragma HLS INTERFACE ap_ovld register port=po_rx_ports name=poROL_NRC_Rx_ports
453 #pragma HLS INTERFACE ap_stable register port=pi_rank name=piFMC_ROL_rank
454 #pragma HLS INTERFACE ap_stable register port=pi_size name=piFMC_ROL_size
455 
456 
457  //-- LOCAL VARIABLES ------------------------------------------------------
458  static NetworkMetaStream meta_tmp = NetworkMetaStream();
459  static stream<NetworkWord> sRxpToTxp_Data("sRxpToTxP_Data"); // FIXME: works even with no static
460  static stream<NetworkMetaStream> sRxtoTx_Meta("sRxtoTx_Meta");
461  static unsigned int processed_word_rx = 0;
462  static unsigned int processed_word_tx = 0;
463  static unsigned int processed_word_proc = 0;
464  static unsigned int struct_loaded = 0;
465  static varin instruct;
466  static DtUsed out[OUTDEP];
467  const int tot_transfers = TOT_TRANSFERS;
468  *po_rx_ports = 0x1; //currently work only with default ports...
469 
470 
471  //-- DIRECTIVES FOR THIS PROCESS ------------------------------------------
472 #pragma HLS DATAFLOW
473 #pragma HLS stream variable=sRxtoTx_Meta depth=tot_transfers
474 //#pragma HLS stream variable=sRxpToTxp_Data depth=2048
475 #pragma HLS reset variable=enqueueFSM
476 #pragma HLS reset variable=dequeueFSM
477 #pragma HLS reset variable=MCEuropeanEngineFSM
478 #pragma HLS reset variable=processed_word_rx
479 #pragma HLS reset variable=processed_word_tx
480 #pragma HLS reset variable=processed_word_proc
481 #pragma HLS reset variable=struct_loaded
482 
483 
484 #ifdef USE_HLSLIB_DATAFLOW
500  // Dataflow functions running in parallel
501  HLSLIB_DATAFLOW_INIT();
502 
503  HLSLIB_DATAFLOW_FUNCTION(pRXPath,
504  siSHL_This_Data,
505  siNrc_meta,
506  &instruct,
507  meta_tmp,
508  &processed_word_rx,
509  &struct_loaded);
510 
511  HLSLIB_DATAFLOW_FUNCTION(pProcPath,
512  sRxpToTxp_Data,
513  sRxtoTx_Meta,
514  meta_tmp,
515  &instruct,
516  out,
517  &processed_word_rx,
518  &processed_word_proc,
519  &struct_loaded);
520 
521  HLSLIB_DATAFLOW_FUNCTION(pTXPath,
522  soTHIS_Shl_Data,
523  soNrc_meta,
524  sRxpToTxp_Data,
525  sRxtoTx_Meta,
526  &processed_word_tx,
527  pi_rank,
528  pi_size);
529 
530  HLSLIB_DATAFLOW_FINALIZE();
531 
532 #else // !USE_HLSLIB_DATAFLOW
533  pRXPath(
534  siSHL_This_Data,
535  siNrc_meta,
536  &instruct,
537  meta_tmp,
538  &processed_word_rx,
539  &struct_loaded);
540 
541 
542  pProcPath(sRxpToTxp_Data,
543  sRxtoTx_Meta,
544  meta_tmp,
545  &instruct,
546  out,
547  &processed_word_rx,
548  &processed_word_proc,
549  &struct_loaded);
550 
551  pTXPath(
552  soTHIS_Shl_Data,
553  soNrc_meta,
554  sRxpToTxp_Data,
555  sRxtoTx_Meta,
556  &processed_word_tx,
557  pi_rank,
558  pi_size);
559 #endif // USE_HLSLIB_DATAFLOW
560 }
561 
562 
uint8_t enqueueFSM
void pProcPath(stream< NetworkWord > &sRxpToTxp_Data, stream< NetworkMetaStream > &sRxtoTx_Meta, NetworkMetaStream meta_tmp, varin *instruct, double *out, unsigned int *processed_word_rx, unsigned int *processed_word_proc, unsigned int *struct_loaded)
Processing Path - Main processing FSM for Vitis kernels.
void mceuropeanengine(ap_uint< 32 > *pi_rank, ap_uint< 32 > *pi_size, stream< NetworkWord > &siSHL_This_Data, stream< NetworkWord > &soTHIS_Shl_Data, stream< NetworkMetaStream > &siNrc_meta, stream< NetworkMetaStream > &soNrc_meta, ap_uint< 32 > *po_rx_ports)
Main process of the MCEuropeanEngine Application directives.
void pTXPath(stream< NetworkWord > &soTHIS_Shl_Data, stream< NetworkMetaStream > &soNrc_meta, stream< NetworkWord > &sRxpToTxp_Data, stream< NetworkMetaStream > &sRxtoTx_Meta, unsigned int *processed_word_tx, ap_uint< 32 > *pi_rank, ap_uint< 32 > *pi_size)
Transmit Path - From THIS to SHELL.
#define MCEUROPEANENGINE_RETURN_RESULTS
void storeWordToStruct(NetworkWord word, varin *instruct, unsigned int *processed_word_rx, unsigned int *struct_loaded)
Store a word from ethernet to a local AXI stream.
#define BITS_PER_10GBITETHRNET_AXI_PACKET
void pRXPath(stream< NetworkWord > &siSHL_This_Data, stream< NetworkMetaStream > &siNrc_meta, varin *instruct, NetworkMetaStream meta_tmp, unsigned int *processed_word_rx, unsigned int *struct_loaded)
Receive Path - From SHELL to THIS.
uint8_t dequeueFSM
#define INPUT_PTR_WIDTH
#define PROCESSING_WAIT
uint8_t MCEuropeanEngineFSM
long unsigned int DtUsedInt
Definition: config.h:74
#define OUTDEP
Definition: config.h:63
#define DtUsed
Definition: config.h:57
#define TOT_TRANSFERS
Definition: config.h:70
#define PacketFsmType
Definition: memtest.hpp:76
#define PROCESSING_PACKET
Definition: memtest.hpp:73
#define WAIT_FOR_STREAM_PAIR
Definition: memtest.hpp:72
#define WAIT_FOR_META
Definition: memtest.hpp:71
#define PACK_SIZE
Definition: config.h:51
void kernel_mc(DtUsedInt loop_nm, DtUsedInt seed, DtUsed underlying, DtUsed volatility, DtUsed dividendYield, DtUsed riskFreeRate, DtUsed timeLength, DtUsed strike, DtUsedInt optionType, DtUsed out[OUTDEP], DtUsed requiredTolerance, DtUsedInt requiredSamples, DtUsedInt timeSteps, DtUsedInt maxSamples, bool *finished)
out
Definition: test.py:12
ap_uint< 8 > NodeId
Definition: network.hpp:82
ap_uint< 1 > tlast
Definition: network.hpp:111
ap_uint< 8 > tkeep
Definition: network.hpp:110
NetworkMeta tdata
Definition: network.hpp:109
NodeId dst_rank
Definition: network.hpp:95
NodeId src_rank
Definition: network.hpp:97
NrcPort src_port
Definition: network.hpp:98
NrcPort dst_port
Definition: network.hpp:96
ap_uint< 64 > tdata
Definition: network.hpp:49
ap_uint< 8 > tkeep
Definition: network.hpp:50
ap_uint< 1 > tlast
Definition: network.hpp:51
Definition: config.h:85
double dividendYield
Definition: config.h:90
DtUsedInt seed
Definition: config.h:87
DtUsedInt maxSamples
Definition: config.h:98
double riskFreeRate
Definition: config.h:91
double volatility
Definition: config.h:89
double requiredTolerance
Definition: config.h:95
DtUsedInt loop_nm
Definition: config.h:86
double underlying
Definition: config.h:88
DtUsedInt timeSteps
Definition: config.h:97
double strike
Definition: config.h:93
DtUsedInt requiredSamples
Definition: config.h:96
DtUsedInt optionType
Definition: config.h:94
double timeLength
Definition: config.h:92
double f
Definition: config.h:103
DtUsedInt i
Definition: config.h:104