cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
mceuropeanengine_host_fwd_tb.cpp
Go to the documentation of this file.
1 
17 
32 #include <cstdlib> // For atoi()
33 #include <iostream> // For cout and cerr
34 #include <cstdio>
35 #include <memory>
36 #include <stdexcept>
37 #include <string>
38 #include <string.h>
39 #include <assert.h> // For assert()
40 #include <array>
41 #include <sys/stat.h>
42 #include <fstream>
43 #include <limits>
44 #include "../../../../../PracticalSockets/src/PracticalSockets.h"
45 #include "../include/config.h"
46 
47 
48 static inline unsigned int
49 fileRead(const char *fname, DtUsed *buff, size_t len) {
50 
51  if ((fname == NULL) || (buff == NULL) || (len == 0))
52  return -EINVAL;
53 
54  std::ifstream ifile(fname, std::ios::in);
55 
56  //check to see that the file was opened correctly:
57  if (!ifile.is_open()) {
58  std::cerr << "ERROR: There was a problem opening the input file " + string(fname)+ " \n";
59  return -EIO;
60  }
61 
62  unsigned int i = 0;
63  string text;
64  //keep storing values from the text file so long as data exists:
65  while (ifile >> text) {
66  if((text == "Inf") || (text == "-Inf")) {
67  buff[i] = (DtUsed)std::numeric_limits<double>::infinity();
68  }
69  else if((text == "nan") || (text == "-nan")) {
70  buff[i] = (DtUsed)std::numeric_limits<double>::quiet_NaN();
71  }
72  else {
73  buff[i] = (DtUsed)atof(text.c_str());
74  }
75  //cout << "DEBUG fileRead: " << i << " : " << buff[i] << endl;
76  i++;
77  if (i == len) {
78  break;
79  }
80  }
81  // We ensure the reading of len values, not less or more
82  assert (i == len);
83  return i;
84 }
85 
86 
87 
88 
89 
96 unsigned int
97 writeStructToConfFile(const char *fname, varin *instruct) {
98 
99  if ((fname == NULL) || (instruct == NULL))
100  return -EINVAL;
101 
102  std::ofstream ifile(fname);
103 
104  //check to see that the file was opened correctly:
105  if (!ifile.is_open()) {
106  std::cerr << "There was a problem creating the output file!\n";
107  return -EIO;
108  }
109  unsigned int i, j;
110  for (i = 0, j = 0; i < sizeof(varin); i+=sizeof(DtUsed), j++) {
111  switch(j)
112  {
113  case 0:
114  ifile << instruct->loop_nm << endl;
115  break;
116  case 1:
117  ifile << instruct->seed << endl;
118  break;
119  case 2:
120  ifile << instruct->underlying << endl;
121  break;
122  case 3:
123  ifile << instruct->volatility << endl;
124  break;
125  case 4:
126  ifile << instruct->dividendYield << endl;
127  break;
128  case 5:
129  ifile << instruct->riskFreeRate << endl;
130  break;
131  case 6:
132  ifile << instruct->timeLength << endl;
133  break;
134  case 7:
135  ifile << instruct->strike << endl;
136  break;
137  case 8:
138  ifile << instruct->optionType << endl;
139  break;
140  case 9:
141  ifile << instruct->requiredTolerance << endl;
142  break;
143  case 10:
144  ifile << instruct->requiredSamples << endl;
145  break;
146  case 11:
147  ifile << instruct->timeSteps << endl;
148  break;
149  case 12:
150  ifile << instruct->maxSamples << endl;
151  break;
152  default:
153  break;
154  }
155  }
156  ifile.close();
157  return (i);
158 }
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
175 int main(int argc, char * argv[]) {
176 
177  if ((argc < 2) || (argc > 3)) { // Test for correct number of parameters
178  cerr << "Usage: " << argv[0] << " <Server Port> <optional simulation mode>" << endl;
179  exit(1);
180  }
181 
182  unsigned short servPort = atoi(argv[1]); // First arg: local port
183  if ((servPort <= 0) || (servPort <= 1024) || (servPort >= 65536)) {
184  cerr << "ERROR: Invalid port number " << servPort <<
185  ". Please select a value at range [1025-65535]. Aborting..." << endl;
186  exit(1);
187  }
188  unsigned int num_batch = 0;
189  string clean_cmd, synth_cmd;
190 
191  try {
192  cout << " ___________________________________________________________________ " << endl;
193  cout << "/ \\" << endl;
194  cout << "INFO: Proxy tb batch # " << ++num_batch << endl;
195  #if NET_TYPE == udp
196  UDPSocket sock(servPort);
197  #else
198  TCPServerSocket servSock(servPort); // Server Socket object
199  TCPSocket *servsock = servSock.accept();// Wait for a client to connect
200  #endif
201  char buffer[BUF_LEN]; // Buffer for echo string
202  unsigned int recvMsgSize; // Size of received message
203  string sourceAddress = "localhost"; // Address of datagram source
204 
205  #if NET_TYPE == tcp
206  // TCP client handling
207  cout << "Handling client ";
208  try {
209  cout << servsock->getForeignAddress() << ":";
210  } catch (SocketException e) {
211  cerr << "Unable to get foreign address" << endl;
212  }
213  try {
214  cout << servsock->getForeignPort();
215  } catch (SocketException e) {
216  cerr << "Unable to get foreign port" << endl;
217  }
218  cout << endl;
219  #endif
220 
221  // RX Step
222  clock_t last_cycle_rx = clock();
223 
224  // Block until receive message from a client
225  varin instruct;
226  int input_string_total_len = 0;
227  #if NET_TYPE == tcp
228  int receiving_now_rx = sizeof(instruct);
229  #endif
230  int total_pack_rx = 1 + (sizeof(instruct) - 1) / PACK_SIZE;
231  char * longbuf = new char[PACK_SIZE * total_pack_rx];
232 
233  // RX Loop
234  for (unsigned int i = 0; i < sizeof(instruct); ) {
235  #if NET_TYPE == udp
236  recvMsgSize = sock.recvFrom(buffer, BUF_LEN, sourceAddress, servPort);
237  #else
238  recvMsgSize = servsock->recv(buffer, receiving_now_rx);
239  #endif
240  input_string_total_len += recvMsgSize;
241  //bytes_in_last_pack_rx = recvMsgSize;
242  memcpy( & longbuf[i * PACK_SIZE], buffer, recvMsgSize);
243  i += recvMsgSize;
244  }
245  memcpy(&instruct, & longbuf[0], sizeof(instruct));
246  cout << "INFO: Received packet from " << sourceAddress << ":" << servPort << endl;
247 
248  printf("DEBUG instruct.loop_nm = %u\n", (unsigned int)instruct.loop_nm);
249  printf("DEBUG instruct.seed = %u\n", (unsigned int)instruct.seed);
250  printf("DEBUG instruct.underlying = %f\n", instruct.underlying);
251  printf("DEBUG instruct.volatility = %f\n", instruct.volatility);
252  printf("DEBUG instruct.dividendYield = %f\n", instruct.dividendYield);
253  printf("DEBUG instruct.riskFreeRate = %f\n", instruct.riskFreeRate);
254  printf("DEBUG instruct.timeLength = %f\n", instruct.timeLength);
255  printf("DEBUG instruct.strike = %f\n", instruct.strike);
256  printf("DEBUG instruct.optionType = %u\n", (unsigned int)instruct.optionType);
257  printf("DEBUG instruct.requiredTolerance = %f\n", instruct.requiredTolerance);
258  printf("DEBUG instruct.requiredSamples = %u\n", (unsigned int)instruct.requiredSamples);
259  printf("DEBUG instruct.timeSteps = %u\n", (unsigned int)instruct.timeSteps);
260  printf("DEBUG instruct.maxSamples = %u\n", (unsigned int)instruct.maxSamples);
261 
262  if (writeStructToConfFile("../../../../../../ROLE/quantitative_finance/hls/mceuropeanengine/etc/mce_from_net.conf", &instruct) != sizeof(varin)) {
263  cerr << "ERROR: Cannot write struct to configuration file. Aborting ..." << endl;
264  return (-1);
265  }
266 
267  // Select simulation mode, default fcsim
268  synth_cmd = " ";
269  string exec_cmd = "make fcsim -j 4";
270  string ouf_file = "../../../../../../ROLE/quantitative_finance/hls/mceuropeanengine/mceuropeanengine_prj/solution1/fcsim/build/hls_out.txt";
271  if (argc == 3) {
272  if (atoi(argv[2]) == 2) {
273  exec_cmd = "make csim";
274  ouf_file = "../../../../../../ROLE/quantitative_finance/hls/mceuropeanengine/mceuropeanengine_prj/solution1/csim/build/hls_out.txt";
275  }
276  else if (atoi(argv[2]) == 3) {
277  synth_cmd = "make csynth && ";
278  exec_cmd = "make cosim";
279  ouf_file = "../../../../../../ROLE/quantitative_finance/hls/mceuropeanengine/mceuropeanengine_prj/solution1/sim/wrapc_pc/hls_out.txt";
280  }
281  else if (atoi(argv[2]) == 4) {
282  exec_cmd = "make kcachegrind";
283  ouf_file = "../../../../../../ROLE/quantitative_finance/mceuropeanengine/mceuropeanengine_prj/solution1/fcsim/build/hls_out.txt";
284  }
285  }
286  // Calling the actual TB over its typical makefile procedure, but passing the save file
287  // Skip the rebuilding phase on the 2nd run. However ensure that it's a clean recompile
288  // the first time.
289  clean_cmd = " ";
290  if (num_batch == 1) {
291  clean_cmd = "make clean && ";
292  }
293 
294  string str_command = "cd ../../../../../../ROLE/quantitative_finance/hls/mceuropeanengine/ && " + clean_cmd + synth_cmd + "\
295  INPUT_FILE=./etc/mce_from_net.conf " + exec_cmd + " && \
296  cd ../../../../HOST/quantitative_finance/mceuropeanengine/languages/cplusplus/build/ ";
297  const char *command = str_command.c_str();
298  cout << "Calling TB with command:" << command << endl;
299  system(command);
300 
301 
302  ssize_t size = instruct.loop_nm*sizeof(DtUsed);
303  unsigned int total_pack_tx = 1 + (size - 1) / PACK_SIZE;
304  unsigned int bytes_in_last_pack_tx = instruct.loop_nm*sizeof(DtUsed) - (total_pack_tx - 1) * PACK_SIZE;
305 
306 
307  // Reallocate longbuf for Tx size
308  delete longbuf;
309  longbuf = new char[PACK_SIZE * total_pack_tx];
310  memset(longbuf, 0, PACK_SIZE * total_pack_tx * sizeof(char));
311  DtUsed * out = new DtUsed[instruct.loop_nm];
312  memset(out, 0, instruct.loop_nm * sizeof(DtUsed));
313  unsigned int rc = fileRead(ouf_file.c_str(), out, instruct.loop_nm);
314  if (rc < 0) {
315  cerr << "ERROR: Cannot read file " << ouf_file << " . Aborting..."<< endl;
316  return -1;
317  }
318 
319  memcpy(longbuf, out, instruct.loop_nm*sizeof(DtUsed));
320 
321  clock_t next_cycle_rx = clock();
322  double duration_rx = (next_cycle_rx - last_cycle_rx) / (double) CLOCKS_PER_SEC;
323  cout << "INFO: Effective FPS RX:" << (1 / duration_rx) << " \tkbps:" << (PACK_SIZE *
324  total_pack_rx / duration_rx / 1024 * 8) << endl;
325  last_cycle_rx = next_cycle_rx;
326 
327 
328  // TX step
329  cout << "INFO: Succesfully received out vector from TB " << endl;
330  cout << "INFO: Will forward it back to host app ... total_pack_tx=" << total_pack_tx << endl;
331 
332 
333  // TX Loop
334  unsigned int sending_now = PACK_SIZE;
335  clock_t last_cycle_tx = clock();
336  for (unsigned int i = 0; i < total_pack_tx; i++) {
337  if ( i == total_pack_tx - 1 ) {
338  sending_now = bytes_in_last_pack_tx;
339  }
340  #if NET_TYPE == udp
341  sock.sendTo( & longbuf[i * PACK_SIZE], sending_now, sourceAddress, servPort);
342  #else
343  servsock->send( & longbuf[i * PACK_SIZE], sending_now);
344  #endif
345  }
346 
347  clock_t next_cycle_tx = clock();
348  double duration_tx = (next_cycle_tx - last_cycle_tx) / (double) CLOCKS_PER_SEC;
349  cout << "INFO: Effective FPS TX:" << (1 / duration_tx) << " \tkbps:" << (PACK_SIZE *
350  (total_pack_rx + total_pack_tx)/ duration_tx / 1024 * 8) << endl;
351  last_cycle_tx = next_cycle_tx;
352  delete longbuf;
353  delete out;
354  cout << "\\___________________________________________________________________/" << endl;
355 
356  #if NET_TYPE == tcp
357  delete servsock;
358  #endif
359  } catch (SocketException & e) {
360  cerr << e.what() << endl;
361  exit(1);
362  }
363  return 0;
364 }
365 
366 
int main()
Definition: tb_fmc.cpp:380
#define DtUsed
Definition: config.h:57
#define BUF_LEN
Definition: config.h:54
#define PACK_SIZE
Definition: config.h:51
unsigned int writeStructToConfFile(const char *fname, varin *instruct)
Fill an output file with data from an image.
out
Definition: test.py:12
def clock()
Definition: common.py:174
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
ap_uint< 32 > size