cloudFPGA (cF) API  1.0
The documentation of the source code of cloudFPGA (cF)
uppercase_host.cpp
Go to the documentation of this file.
1 
17 
33 #include <stdio.h>
34 #include <iostream> // For cout and cerr
35 #include <cstdlib> // For atoi()
36 #include <assert.h> // For assert()
37 #include <string> // For to_string
38 #include <string.h>
39 #include "PracticalSockets.h" // For UDPSocket and SocketException
40 #include "../include/config.h"
41 
42 using namespace std;
43 
44 
45 void delay(unsigned int mseconds)
46 {
47  clock_t goal = mseconds + clock();
48  while (goal > clock());
49 }
50 
51 
52 void print_cFpZoo(void)
53  // http://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=cFp_Zoo
54 {
55  cout << " " << endl;
56  cout << "...build with: " << endl;
57  cout << " ██████╗███████╗██████╗ ███████╗ ██████╗ ██████╗ " << endl;
58  cout << "██╔════╝██╔════╝██╔══██╗ ╚══███╔╝██╔═══██╗██╔═══██╗ " << endl;
59  cout << "██║ █████╗ ██████╔╝ ███╔╝ ██║ ██║██║ ██║ " << endl;
60  cout << "██║ ██╔══╝ ██╔═══╝ ███╔╝ ██║ ██║██║ ██║ " << endl;
61  cout << "╚██████╗██║ ██║███████╗███████╗╚██████╔╝╚██████╔╝ " << endl;
62  cout << " ╚═════╝╚═╝ ╚═╝╚══════╝╚══════╝ ╚═════╝ ╚═════╝ " << endl;
63  cout << "A cloudFPGA project from IBM ZRL v1.0 " << endl;
64  cout << "Quantitative Finance Monte-Carlo European Pricing Engine " << endl;
65 }
66 
67 
68 
69 #ifdef PY_WRAP
70 int uppercase(char *s_servAddress, char *s_servPort, char *input_str, char *output_str, bool net_type)
71 {
72 #else
77 int main(int argc, char *argv[])
78 {
79  if ((argc < 3) || (argc > 4)) { // Test for correct number of arguments
80  cerr << "Usage: " << argv[0] << " <Server> <Server Port> <input string> <optional output string>\n";
81  exit(1);
82  }
83 #endif
84 
85 
86  //------------------------------------------------------
87  //-- STEP-1 : Socket and variables definition
88  //------------------------------------------------------
89 
90  #ifndef PY_WRAP
91  assert (argc == 4);
92  string s_servAddress = argv[1]; // First arg: server address
93  char *s_servPort = argv[2];
94  bool net_type = NET_TYPE;
95  #endif
96 
97  string servAddress = s_servAddress;
98  unsigned short servPort;
99  if (net_type == udp) {
100  servPort = Socket::resolveService(s_servPort, "udp");
101  }
102  else if (net_type == tcp) {
103  servPort = atoi(s_servPort);
104  }
105  else {
106  cout << "ERROR: Invalid type of socket type provided: " << net_type << " Choosed one of (tcp=0 or udp=1)" << endl;
107  }
108 
109  char buffer[BUF_LEN]; // Buffer for echo string
110  unsigned int recvMsgSize; // Size of received message
111  unsigned int num_frame = 0;
112  std::string input_string;
113  //UDPSocket *udpsock_p;
114  //TCPSocket *tcpsock_p;
115 
116  print_cFpZoo();
117 
118  try {
119 
120  //------------------------------------------------------
121  //-- STEP-2 : Initialize socket connection
122  //------------------------------------------------------
123  #if NET_TYPE == udp
124  #ifndef TB_SIM_CFP_VITIS
125  UDPSocket udpsock(servPort); // NOTE: It is very important to set port here in order to call
126  // bind() in the UDPSocket constructor
127  #else // TB_SIM_CFP_VITIS
128  UDPSocket udpsock; // NOTE: In HOST TB the port is already binded by uppercase_host_fwd_tb.cpp
129  #endif // TB_SIM_CFP_VITIS
130  // udpsock_p = &udpsock;
131  #else // tcp
132  TCPSocket tcpsock(servAddress, servPort);
133  // tcpsock_p = &tcpsock;
134  #endif // udp/tcp
135 
136  //------------------------------------------------------------------------------------
137  //-- STEP-3 : Create a string from input argument
138  //------------------------------------------------------------------------------------
139  #ifdef PY_WRAP
140  input_string.assign(input_str);
141  #else
142  input_string.assign(argv[3]);
143  #endif
144  if (input_string.length() == 0) {
145  cerr << "Empty string provided. Aborting...\n\n" << endl;
146  exit(1);
147  }
148 
149  clock_t start_cycle_main = clock();
150  cout << " ___________________________________________________________________ " << endl;
151  cout << "/ \\" << endl;
152  cout << "INFO: Batch # " << ++num_frame << endl;
153 
154  // Ensure that the selection of MTU is a multiple of 8 (Bytes per transaction)
155  assert(PACK_SIZE % 8 == 0);
156 
157  unsigned int total_pack = 1 + (input_string.length() - 1) / PACK_SIZE;
158  unsigned int total_bytes = total_pack * PACK_SIZE;
159  unsigned int bytes_in_last_pack = input_string.length() - (total_pack - 1) * PACK_SIZE;
160 
161  cout << "INFO: Network socket : " << ((net_type == tcp) ? "TCP" : "UDP") << endl;
162  cout << "INFO: Total packets to send/receive = " << total_pack << endl;
163  cout << "INFO: Total bytes to send/receive = " << input_string.length() << endl;
164  cout << "INFO: Total bytes in " << total_pack << " packets = " << total_bytes << endl;
165  cout << "INFO: Bytes in last packet = " << bytes_in_last_pack << endl;
166  cout << "INFO: Packet size (custom MTU) = " << PACK_SIZE << endl;
167 
168  //------------------------------------------------------
169  //-- STEP-4 : RUN UPPERCASE FROM cF (HW)
170  //------------------------------------------------------
171  clock_t start_cycle_uppercase_hw = clock();
172 
173  //------------------------------------------------------
174  //-- STEP-5.1 : TX Loop
175  //------------------------------------------------------
176  clock_t last_cycle_tx = clock();
177  unsigned int sending_now = PACK_SIZE;
178  for (unsigned int i = 0; i < total_pack; i++) {
179  if ( i == total_pack - 1 ) {
180  sending_now = bytes_in_last_pack;
181  }
182  #if NET_TYPE == udp
183  udpsock.sendTo( & input_string[i * PACK_SIZE], sending_now, servAddress, servPort);
184  #else
185  tcpsock.send( & input_string[i * PACK_SIZE], sending_now);
186  #endif
187  delay(1000);
188  }
189  clock_t next_cycle_tx = clock();
190  double duration_tx = (next_cycle_tx - last_cycle_tx) / (double) CLOCKS_PER_SEC;
191  cout << "INFO: Effective SPS TX:" << (1 / duration_tx) << " \tkbps:" << (PACK_SIZE *
192  total_pack / duration_tx / 1024 * 8) << endl;
193  last_cycle_tx = next_cycle_tx;
194 
195 
196  //------------------------------------------------------
197  //-- STEP-5.2 : RX Loop
198  //------------------------------------------------------
199  clock_t last_cycle_rx = clock();
200  unsigned int receiving_now = PACK_SIZE;
201  cout << "INFO: Expecting length of packs:" << total_pack << endl;
202  char * longbuf = new char[PACK_SIZE * total_pack];
203  for (unsigned int i = 0; i < input_string.length(); ) {
204  //cout << "DEBUG: " << i << endl;
205  if ( i == total_pack - 1 ) {
206  receiving_now = bytes_in_last_pack;
207  }
208  #if NET_TYPE == udp
209  recvMsgSize = udpsock.recvFrom(buffer, BUF_LEN, servAddress, servPort);
210  #else
211  recvMsgSize = tcpsock.recv(buffer, BUF_LEN);
212  #endif
213  if (recvMsgSize != receiving_now) {
214  cerr << "WARNING: Received unexpected size pack:" << recvMsgSize << ". Expected: " <<
215  receiving_now << endl;
216  }
217  memcpy( & longbuf[i], buffer, recvMsgSize);
218  //cout << "DEBUG: recvMsgSize=" << recvMsgSize << endl;
219  i += recvMsgSize;
220  }
221 
222  cout << "INFO: Received packet from " << servAddress << ":" << servPort << endl;
223 
224  #ifdef PY_WRAP
225  char *output_string = output_str;
226  #else
227  char *output_string = (char*)malloc((input_string.length()+1)*sizeof(char));
228  #endif
229  output_string = strncpy(output_string, longbuf, input_string.length());
230  output_string[input_string.length()]='\0';
231  cout << "INFO: Received string : " << output_string << endl;
232  clock_t next_cycle_rx = clock();
233  double duration_rx = (next_cycle_rx - last_cycle_rx) / (double) CLOCKS_PER_SEC;
234  cout << "INFO: Effective SPS RX:" << (1 / duration_rx) << " \tkbps:" << (PACK_SIZE *
235  total_pack / duration_rx / 1024 * 8) << endl;
236  last_cycle_rx = next_cycle_rx;
237 
238  clock_t end_cycle_uppercase_hw = next_cycle_rx;
239 
240  double duration_uppercase_hw = (end_cycle_uppercase_hw - start_cycle_uppercase_hw) /
241  (double) CLOCKS_PER_SEC;
242  cout << "INFO: HW exec. time:" << duration_uppercase_hw << " seconds" << endl;
243  cout << "INFO: Effective SPS HW:" << (1 / duration_uppercase_hw) << " \tkbps:" <<
244  (PACK_SIZE * total_pack / duration_uppercase_hw / 1024 * 8) << endl;
245 
246  double duration_main = (clock() - start_cycle_main) / (double) CLOCKS_PER_SEC;
247  cout << "INFO: Effective SPS E2E:" << (1 / duration_main) << endl;
248  cout << "\\___________________________________________________________________/" << endl
249  << endl;
250 
251  // Destructor closes the socket
252  } catch (SocketException & e) {
253  cerr << e.what() << endl;
254  exit(1);
255  }
256 
257  return 0;
258 }
259 
260 
261 
262 
cat GET request dos socat stdio tcp
Definition: commands.txt:1
#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
void uppercase(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 Uppercase Application directives.
Definition: uppercase.cpp:335
int main(int argc, char *argv[])
void print_cFpZoo(void)
void delay(unsigned int mseconds)
def clock()
Definition: common.py:174