cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
MCEuropeanEngine

This is the MCEuropeanEngine accelerated function from Vitis Quantitative Finance Open Source Library. More...

Collaboration diagram for MCEuropeanEngine:

Modules

 MCEuropeanEngine Testbench
 This is a subgroup of MCEuropeanEngine accelerated function with only testbench-related functions/classes/.
 
 MCEuropeanEngine Vivado HLS
 This is a subgroup of MCEuropeanEngine accelerated function with only synthesizable (Vivado HLS) functions/classes.
 
 MCEuropeanEngine Host
 This is a subgroup of MCEuropeanEngine accelerated function with only host code software.
 

Files

file  config.h
 The configuration of a MCEuropeanEngine application (UDP or TCP)
 
file  mceuropeanengine_host.cpp
 mceuropeanengine userspace application for cF (x86, ppc64).
 

Classes

struct  varin
 
union  intToFloatUnion
 

Macros

#define CEIL(a, b)   (((a) + (b-1)) / (b))
 
#define PACK_SIZE   1024
 
#define BUF_LEN   65540
 
#define NET_TYPE   udp
 
#define DtUsed   double
 
#define MCM_NM   6
 
#define OUTDEP   1024
 
#define TOT_TRANSFERS_IN   (CEIL(INSIZE, PACK_SIZE))
 
#define TOT_TRANSFERS_OUT   (CEIL(OUTSIZE, PACK_SIZE))
 
#define TOT_TRANSFERS   TOT_TRANSFERS_IN + TOT_TRANSFERS_OUT
 
#define tcp   0
 
#define udp   1
 

Typedefs

typedef long unsigned int DtUsedInt
 

Functions

void delay (unsigned int mseconds)
 
void print_cFpZoo (void)
 
int main (int argc, char *argv[])
 

Detailed Description

This is the MCEuropeanEngine accelerated function from Vitis Quantitative Finance Open Source Library.

cFDK / cFp / cFp_Zoo / VitisQuantitativeFinance : Submodules

Macro Definition Documentation

◆ BUF_LEN

#define BUF_LEN   65540

Larger than maximum UDP packet size

Definition at line 48 of file config.h.

◆ CEIL

#define CEIL (   a,
 
)    (((a) + (b-1)) / (b))

Ceiling function without using math.h

Definition at line 37 of file config.h.

◆ DtUsed

#define DtUsed   double

The data type of MCEuropeanEngine, that determines the precision. Either float or double.

Definition at line 57 of file config.h.

◆ MCM_NM

#define MCM_NM   6

The number of MCEuropean Engines running in parallel with differnet seed.

Definition at line 60 of file config.h.

◆ NET_TYPE

#define NET_TYPE   udp

The network socket type: tcp or udp

Definition at line 54 of file config.h.

◆ OUTDEP

#define OUTDEP   1024

The number of execution loops, thus the depth of the output values' vector.

Definition at line 63 of file config.h.

◆ PACK_SIZE

#define PACK_SIZE   1024

This is our custom MTU. We must use a multiple of 8 (Bytes per transaction)! 1450 4086 udp pack size; note that OSX limits < 8100 bytes

Definition at line 45 of file config.h.

◆ tcp

#define tcp   0

Definition at line 79 of file config.h.

◆ TOT_TRANSFERS

#define TOT_TRANSFERS   TOT_TRANSFERS_IN + TOT_TRANSFERS_OUT

Definition at line 70 of file config.h.

◆ TOT_TRANSFERS_IN

#define TOT_TRANSFERS_IN   (CEIL(INSIZE, PACK_SIZE))

The total TxRx transfers for a predefined MTU=PACK_SIZE

Definition at line 68 of file config.h.

◆ TOT_TRANSFERS_OUT

#define TOT_TRANSFERS_OUT   (CEIL(OUTSIZE, PACK_SIZE))

Definition at line 69 of file config.h.

◆ udp

#define udp   1

Definition at line 80 of file config.h.

Typedef Documentation

◆ DtUsedInt

typedef long unsigned int DtUsedInt

Definition at line 74 of file config.h.

Function Documentation

◆ delay()

void delay ( unsigned int  mseconds)

Definition at line 47 of file mceuropeanengine_host.cpp.

48 {
49  clock_t goal = mseconds + clock();
50  while (goal > clock());
51 }
def clock()
Definition: common.py:174
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)

Main testbench and user-application for mceuropeanengine on host. Client

Returns
O on success, 1 on fail

Definition at line 88 of file mceuropeanengine_host.cpp.

89 {
90  if ((argc < 3) || (argc > 4)) { // Test for correct number of arguments
91  cerr << "Usage: " << argv[0] << " <Server> <Server Port> \n";
92  exit(1);
93  }
94 #endif
95 
96 
97  //------------------------------------------------------
98  //-- STEP-1 : Socket and variables definition
99  //------------------------------------------------------
100 
101  #ifndef PY_WRAP
102  assert (argc == 3);
103  string s_servAddress = argv[1]; // First arg: server address
104  char *s_servPort = argv[2];
105  #endif
106 
107  string servAddress = s_servAddress;
108  unsigned short servPort;
109  bool net_type = NET_TYPE;
110  if (net_type == udp) {
111  servPort = Socket::resolveService(s_servPort, "udp");
112  }
113  else if (net_type == tcp) {
114  servPort = atoi(s_servPort);
115  }
116  else {
117  cout << "ERROR: Invalid type of socket type provided: " << net_type << " Choosed one of (tcp=0 or udp=1)" << endl;
118  }
119 
120  if ((servPort <= 0) || (servPort <= 1024) || (servPort >= 65536)) {
121  cerr << "ERROR: Invalid port number " << servPort <<
122  ". Please select a value at range [1025-65535]. Aborting..." << endl;
123  exit(1);
124  }
125 
126  char buffer[BUF_LEN]; // Buffer for echo string
127  unsigned int recvMsgSize; // Size of received message
128  unsigned int num_frame = 0;
129  std::string input_string;
130  //UDPSocket *udpsock_p;
131  //TCPSocket *tcpsock_p;
132 
133  print_cFpZoo();
134 
135  try {
136 
137  //------------------------------------------------------
138  //-- STEP-2 : Initialize socket connection
139  //------------------------------------------------------
140  #if (NET_TYPE == udp)
141  #ifndef TB_SIM_CFP_VITIS
142  UDPSocket udpsock(servPort); // NOTE: It is very important to set port here in order to call
143  // bind() in the UDPSocket constructor
144  #else // TB_SIM_CFP_VITIS
145  UDPSocket udpsock; // NOTE: In HOST TB the port is already binded by mceuropeanengine_host_fwd_tb.cpp
146  #endif // TB_SIM_CFP_VITIS
147  //udpsock_p = &udpsock;
148  #else // tcp
149  TCPSocket tcpsock(servAddress, servPort);
150  //tcpsock_p = &tcpsock;
151  #endif // udp/tcp
152 
153  //------------------------------------------------------------------------------------
154  //-- STEP-3 : Create an input struct
155  //------------------------------------------------------------------------------------
156  varin instruct;
157  #ifndef PY_WRAP
158  instruct.loop_nm = OUTDEP;
159  instruct.timeSteps = 1;
160  instruct.requiredTolerance = 0.02f;
161  instruct.underlying = 36;
162  instruct.riskFreeRate = 0.06;
163  instruct.volatility = 0.20;
164  instruct.dividendYield = 0.0;
165  instruct.strike = 40;
166  instruct.optionType = 1;
167  instruct.timeLength = 1;
168  instruct.seed = 4332 ; // 441242, 42, 13342;
169  instruct.requiredSamples = 1; // 262144; // 48128;//0;//1024;//0;
170  instruct.maxSamples = 1;
171  #else
172  instruct.loop_nm = loop_nm;
173  instruct.timeSteps = timeSteps;
175  instruct.underlying = underlying;
176  instruct.riskFreeRate = riskFreeRate;
177  instruct.volatility = volatility;
178  instruct.dividendYield = dividendYield;
179  instruct.strike = strike;
180  instruct.optionType = optionType;
181  instruct.timeLength = timeLength;
182  instruct.seed = seed;
183  instruct.requiredSamples = requiredSamples;
184  instruct.maxSamples = maxSamples;
185  #endif
186 
187  assert(instruct.loop_nm > 0);
188  assert(instruct.loop_nm <= OUTDEP);
189 
190  clock_t start_cycle_main = clock();
191  cout << " ___________________________________________________________________ " << endl;
192  cout << "/ \\" << endl;
193  cout << "INFO: Batch # " << ++num_frame << endl;
194 
195  // Ensure that the selection of MTU is a multiple of 8 (Bytes per transaction)
196  assert(PACK_SIZE % 8 == 0);
197 
198  unsigned int total_pack_tx = 1 + (sizeof(instruct) - 1) / PACK_SIZE;
199  unsigned int total_pack_rx = 1 + (instruct.loop_nm*sizeof(DtUsed) - 1) / PACK_SIZE;
200  unsigned int total_bytes = total_pack_tx * PACK_SIZE;
201  unsigned int bytes_in_last_pack_tx = sizeof(instruct) - (total_pack_tx - 1) * PACK_SIZE;
202  unsigned int bytes_in_last_pack_rx = instruct.loop_nm*sizeof(DtUsed) - (total_pack_rx - 1) * PACK_SIZE;
203 
204  cout << "INFO: Network socket : " << ((net_type == tcp) ? "TCP" : "UDP") << endl;
205  cout << "INFO: Total packets to send : " << total_pack_tx << endl;
206  cout << "INFO: Total packets to receive : " << total_pack_rx << endl;
207  cout << "INFO: Total bytes to send : " << sizeof(instruct) << endl;
208  cout << "INFO: Total bytes to receive : " << instruct.loop_nm*sizeof(DtUsed) << endl;
209  cout << "INFO: Total bytes in " << total_pack_tx << " packets : " << total_bytes << endl;
210  cout << "INFO: Bytes in last packet send: " << bytes_in_last_pack_tx << endl;
211  cout << "INFO: Bytes in last packet recv: " << bytes_in_last_pack_rx << endl;
212  cout << "INFO: Packet size (custom MTU) : " << PACK_SIZE << endl;
213 
214  //------------------------------------------------------
215  //-- STEP-4 : RUN mceuropeanengine FROM cF (HW)
216  //------------------------------------------------------
217  clock_t start_cycle_mceuropeanengine_hw = clock();
218 
219  //------------------------------------------------------
220  //-- STEP-5.1 : TX Loop
221  //------------------------------------------------------
222  clock_t last_cycle_tx = clock();
223  unsigned int sending_now = PACK_SIZE;
224  for (unsigned int i = 0; i < total_pack_tx; i++) {
225  if ( i == total_pack_tx - 1 ) {
226  sending_now = bytes_in_last_pack_tx;
227  }
228  #if (NET_TYPE == udp)
229  udpsock.sendTo( & instruct, sending_now, servAddress, servPort);
230  #else
231  tcpsock.send( & instruct, sending_now);
232  #endif
233  delay(1000);
234  }
235 
236  clock_t next_cycle_tx = clock();
237  double duration_tx = (next_cycle_tx - last_cycle_tx) / (double) CLOCKS_PER_SEC;
238  cout << "INFO: Effective SPS TX:" << (1 / duration_tx) << " \tkbps:" << (PACK_SIZE *
239  total_pack_tx / duration_tx / 1024 * 8) << endl;
240  last_cycle_tx = next_cycle_tx;
241 
242 
243  //------------------------------------------------------
244  //-- STEP-5.2 : RX Loop
245  //------------------------------------------------------
246  clock_t last_cycle_rx = clock();
247  unsigned int receiving_now = PACK_SIZE;
248  cout << "INFO: Expecting length of packs:" << total_pack_rx << endl;
249  char * longbuf = new char[PACK_SIZE * total_pack_rx];
250  memset(longbuf, 0, PACK_SIZE * total_pack_rx);
251  for (unsigned int i = 0; i < instruct.loop_nm*sizeof(DtUsed); ) {
252  //cout << "DEBUG: " << i << endl;
253  if ( i == total_pack_rx - 1 ) {
254  receiving_now = bytes_in_last_pack_rx;
255  }
256  #if (NET_TYPE == udp)
257  recvMsgSize = udpsock.recvFrom(buffer, BUF_LEN, servAddress, servPort);
258  #else
259  recvMsgSize = tcpsock.recv(buffer, BUF_LEN);
260  #endif
261  memcpy( & longbuf[i], buffer, recvMsgSize);
262  i += recvMsgSize;
263  if (recvMsgSize != receiving_now) {
264  cerr << "WARNING: Received unexpected size pack:" << recvMsgSize << ". Expected: " <<
265  receiving_now + " . Breaking Rx..."<< endl;
266  break;
267  }
268  //cout << "DEBUG: recvMsgSize=" << recvMsgSize << endl;
269  }
270 
271  cout << "INFO: Received packet from " << servAddress << ":" << servPort << endl;
272  #ifndef PY_WRAP
273  DtUsed *out = (DtUsed*)malloc(instruct.loop_nm*sizeof(DtUsed));
274  #else
275  DtUsed *out = outarg;
276  #endif
277 
278  for (unsigned int i = 0, j = 0; i < instruct.loop_nm; i++, j+=sizeof(DtUsed)) {
279  memcpy(&out[i], &longbuf[j], sizeof(DtUsed));
280  }
281 
282  cout << "INFO: Received option price vector: " << endl;
283  for (unsigned int i = 0; i < instruct.loop_nm; i++) {
284  cout << i<< " : " << out[i] << endl;
285  }
286 
287  clock_t next_cycle_rx = clock();
288  double duration_rx = (next_cycle_rx - last_cycle_rx) / (double) CLOCKS_PER_SEC;
289  cout << "INFO: Effective SPS RX:" << (1 / duration_rx) << " \tkbps:" << (PACK_SIZE *
290  total_pack_rx / duration_rx / 1024 * 8) << endl;
291  last_cycle_rx = next_cycle_rx;
292 
293  clock_t end_cycle_mceuropeanengine_hw = next_cycle_rx;
294 
295  double duration_mceuropeanengine_hw = (end_cycle_mceuropeanengine_hw - start_cycle_mceuropeanengine_hw) /
296  (double) CLOCKS_PER_SEC;
297  cout << "INFO: HW exec. time:" << duration_mceuropeanengine_hw << " seconds" << endl;
298  cout << "INFO: Effective SPS HW:" << (1 / duration_mceuropeanengine_hw) << " \tkbps:" <<
299  (PACK_SIZE * (total_pack_rx + total_pack_rx) / duration_mceuropeanengine_hw / 1024 * 8) << endl;
300 
301  double duration_main = (clock() - start_cycle_main) / (double) CLOCKS_PER_SEC;
302  #ifndef PY_WRAP
303  free(out);
304  #endif
305  cout << "INFO: Effective SPS E2E:" << (1 / duration_main) << endl;
306  cout << "\\___________________________________________________________________/" << endl
307  << endl;
308 
309  // Destructor closes the socket
310  } catch (SocketException & e) {
311  cerr << e.what() << endl;
312  exit(1);
313  }
314  #ifndef PY_WRAP
315  return 0;
316  #endif
317 }
cat GET request dos socat stdio tcp
Definition: commands.txt:1
void print_cFpZoo(void)
#define OUTDEP
Definition: config.h:63
void delay(unsigned int mseconds)
#define DtUsed
Definition: config.h:57
#define udp
Definition: config.h:66
#define NET_TYPE
Definition: config.h:60
#define BUF_LEN
Definition: config.h:54
#define PACK_SIZE
Definition: config.h:51
int timeSteps
Definition: test.py:37
int requiredSamples
Definition: test.py:36
float volatility
Definition: test.py:29
int optionType
Definition: test.py:34
int seed
Definition: test.py:27
float strike
Definition: test.py:33
int timeLength
Definition: test.py:32
float requiredTolerance
Definition: test.py:35
float underlying
Definition: test.py:28
int maxSamples
Definition: test.py:38
float riskFreeRate
Definition: test.py:31
out
Definition: test.py:12
float dividendYield
Definition: test.py:30
int loop_nm
Definition: test.py:26
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
Here is the call graph for this function:

◆ print_cFpZoo()

void print_cFpZoo ( void  )

Definition at line 54 of file mceuropeanengine_host.cpp.

55 {
56  cout << " " << endl;
57  cout << "...build with: " << endl;
58  cout << " ██████╗███████╗██████╗ ███████╗ ██████╗ ██████╗ " << endl;
59  cout << "██╔════╝██╔════╝██╔══██╗ ╚══███╔╝██╔═══██╗██╔═══██╗ " << endl;
60  cout << "██║ █████╗ ██████╔╝ ███╔╝ ██║ ██║██║ ██║ " << endl;
61  cout << "██║ ██╔══╝ ██╔═══╝ ███╔╝ ██║ ██║██║ ██║ " << endl;
62  cout << "╚██████╗██║ ██║███████╗███████╗╚██████╔╝╚██████╔╝ " << endl;
63  cout << " ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝ " << endl;
64  cout << "A cloudFPGA project from IBM ZRL v1.0 " << endl;
65  cout << "Quantitative Finance Monte-Carlo European Pricing Engine " << endl;
66 }
Here is the caller graph for this function: