VCluster_unit_tests.hpp 12.3 KB
Newer Older
incardon's avatar
incardon committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * VCluster_unit_tests.hpp
 *
 *  Created on: May 9, 2015
 *      Author: Pietro incardona
 */

#ifndef VCLUSTER_UNIT_TESTS_HPP_
#define VCLUSTER_UNIT_TESTS_HPP_

#include "VCluster.hpp"
#include <sstream>
#include <boost/test/included/unit_test.hpp>
#include "timer.hpp"
incardon's avatar
incardon committed
15
#include <random>
incardon's avatar
incardon committed
16
17
18

#define VERBOSE_TEST

incardon's avatar
incardon committed
19
#define N_TRY 2
incardon's avatar
incardon committed
20
#define N_LOOP 67108864
incardon's avatar
incardon committed
21
22
23
24
25
26
27
28
#define BUFF_STEP 524288

BOOST_AUTO_TEST_SUITE( VCluster_test )

size_t global_step = 0;

// Alloc the buffer to receive the messages

incardon's avatar
incardon committed
29
void * msg_alloc(size_t msg_i ,size_t total_msg, size_t total_p, size_t i,size_t ri, void * ptr)
incardon's avatar
incardon committed
30
31
32
{
	openfpm::vector<openfpm::vector<unsigned char>> * v = static_cast<openfpm::vector<openfpm::vector<unsigned char>> *>(ptr);

33
34
35
36
	if (global_v_cluster->getProcessingUnits() <= 8)
		BOOST_REQUIRE_EQUAL(total_p,global_v_cluster->getProcessingUnits()-1);
	else
		BOOST_REQUIRE_EQUAL(total_p,8);
incardon's avatar
incardon committed
37

incardon's avatar
incardon committed
38
	BOOST_REQUIRE_EQUAL(msg_i, global_step);
incardon's avatar
incardon committed
39
40
41
42
43
44
45
46
47
48
	v->get(i).resize(msg_i);

	return &(v->get(i).get(0));
}

// Alloc the buffer to receive the messages

size_t id = 0;
openfpm::vector<size_t> prc_recv;

incardon's avatar
incardon committed
49
void * msg_alloc2(size_t msg_i ,size_t total_msg, size_t total_p, size_t i, size_t ri, void * ptr)
incardon's avatar
incardon committed
50
51
52
53
54
55
{
	openfpm::vector<openfpm::vector<unsigned char>> * v = static_cast<openfpm::vector<openfpm::vector<unsigned char>> *>(ptr);

	v->resize(total_p);
	prc_recv.resize(total_p);

incardon's avatar
incardon committed
56
	BOOST_REQUIRE_EQUAL(msg_i, global_step);
incardon's avatar
incardon committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

	id++;
	v->get(id-1).resize(msg_i);
	prc_recv.get(id-1) = i;
	return &(v->get(id-1).get(0));
}

BOOST_AUTO_TEST_CASE( VCluster_use_reductions)
{
	init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);
	Vcluster & vcl = *global_v_cluster;

	unsigned char uc = 1;
	char c = 1;
	short s = 1;
	unsigned short us = 1;
	int i = 1;
	unsigned int ui = 1;
	long int li = 1;
	unsigned long int uli = 1;
	float f = 1;
	double d = 1;

incardon's avatar
incardon committed
80
81
82
83
84
85
86
87
88
89
90
91
	unsigned char uc_max = vcl.getProcessUnitID();
	char c_max = vcl.getProcessUnitID();
	short s_max = vcl.getProcessUnitID();
	unsigned short us_max = vcl.getProcessUnitID();
	int i_max = vcl.getProcessUnitID();
	unsigned int ui_max = vcl.getProcessUnitID();
	long int li_max = vcl.getProcessUnitID();
	unsigned long int uli_max = vcl.getProcessUnitID();
	float f_max = vcl.getProcessUnitID();
	double d_max = vcl.getProcessUnitID();

	// Sum reductions
incardon's avatar
incardon committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
	if ( vcl.getProcessingUnits() < 128 )
		vcl.reduce(c);
	if ( vcl.getProcessingUnits() < 256 )
		vcl.reduce(uc);
	if ( vcl.getProcessingUnits() < 32768 )
		vcl.reduce(s);
	if ( vcl.getProcessingUnits() < 65536 )
		vcl.reduce(us);
	if ( vcl.getProcessingUnits() < 2147483648 )
		vcl.reduce(i);
	if ( vcl.getProcessingUnits() < 4294967296 )
		vcl.reduce(ui);
	vcl.reduce(li);
	vcl.reduce(uli);
	vcl.reduce(f);
	vcl.reduce(d);
incardon's avatar
incardon committed
108
109
110
111
112
113
114

	// Max reduction
	if ( vcl.getProcessingUnits() < 128 )
		vcl.max(c_max);
	if ( vcl.getProcessingUnits() < 256 )
		vcl.max(uc_max);
	if ( vcl.getProcessingUnits() < 32768 )
incardon's avatar
incardon committed
115
		vcl.max(s_max);
incardon's avatar
incardon committed
116
	if ( vcl.getProcessingUnits() < 65536 )
incardon's avatar
incardon committed
117
		vcl.max(us_max);
incardon's avatar
incardon committed
118
	if ( vcl.getProcessingUnits() < 2147483648 )
incardon's avatar
incardon committed
119
		vcl.max(i_max);
incardon's avatar
incardon committed
120
	if ( vcl.getProcessingUnits() < 4294967296 )
incardon's avatar
incardon committed
121
122
123
124
125
		vcl.max(ui_max);
	vcl.max(li_max);
	vcl.max(uli_max);
	vcl.max(f_max);
	vcl.max(d_max);
incardon's avatar
incardon committed
126
127
128
	vcl.execute();

	if ( vcl.getProcessingUnits() < 128 )
incardon's avatar
incardon committed
129
	{BOOST_REQUIRE_EQUAL(c_max,vcl.getProcessingUnits()-1);}
incardon's avatar
incardon committed
130
	if ( vcl.getProcessingUnits() < 256 )
incardon's avatar
incardon committed
131
	{BOOST_REQUIRE_EQUAL(uc_max,vcl.getProcessingUnits()-1);}
incardon's avatar
incardon committed
132
	if ( vcl.getProcessingUnits() < 32768 )
incardon's avatar
incardon committed
133
	{BOOST_REQUIRE_EQUAL(s_max,vcl.getProcessingUnits()-1);}
incardon's avatar
incardon committed
134
	if ( vcl.getProcessingUnits() < 65536 )
incardon's avatar
incardon committed
135
	{BOOST_REQUIRE_EQUAL(us_max,vcl.getProcessingUnits()-1);}
incardon's avatar
incardon committed
136
	if ( vcl.getProcessingUnits() < 2147483648 )
incardon's avatar
incardon committed
137
	{BOOST_REQUIRE_EQUAL(i_max,vcl.getProcessingUnits()-1);}
incardon's avatar
incardon committed
138
	if ( vcl.getProcessingUnits() < 4294967296 )
incardon's avatar
incardon committed
139
	{BOOST_REQUIRE_EQUAL(ui_max,vcl.getProcessingUnits()-1);}
incardon's avatar
incardon committed
140

incardon's avatar
incardon committed
141
142
143
144
	BOOST_REQUIRE_EQUAL(li_max,vcl.getProcessingUnits()-1);
	BOOST_REQUIRE_EQUAL(uli_max,vcl.getProcessingUnits()-1);
	BOOST_REQUIRE_EQUAL(f_max,vcl.getProcessingUnits()-1);
	BOOST_REQUIRE_EQUAL(d_max,vcl.getProcessingUnits()-1);
incardon's avatar
incardon committed
145
146
147
148
149
150
151
152
153
154
155
156
157
158
}


BOOST_AUTO_TEST_CASE( VCluster_use_sendrecv)
{
	std::cout << "VCluster unit test start" << "\n";
	init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv);

	Vcluster & vcl = *global_v_cluster;

	// send/recv messages

	size_t n_proc = vcl.getProcessingUnits();

incardon's avatar
incardon committed
159
	// Checking short communication pattern
incardon's avatar
incardon committed
160
161
162

	for (size_t s = 0 ; s < N_TRY ; s++)
	{
incardon's avatar
incardon committed
163
		for (size_t j = 32 ; j < N_LOOP ; j*=2)
incardon's avatar
incardon committed
164
165
166
167
168
169
170
171
172
		{
			global_step = j;
			// send message
			openfpm::vector<openfpm::vector<unsigned char>> message;
			// recv message
			openfpm::vector<openfpm::vector<unsigned char>> recv_message(n_proc);

			openfpm::vector<size_t> prc;

173
			for (size_t i = 0 ; i < 8  && i < n_proc ; i++)
incardon's avatar
incardon committed
174
			{
175
176
				size_t p_id = (i + 1 + vcl.getProcessUnitID()) % n_proc;
				if (p_id != vcl.getProcessUnitID())
incardon's avatar
incardon committed
177
				{
178
					prc.add(p_id);
incardon's avatar
incardon committed
179
180
					message.add();
					std::ostringstream msg;
181
					msg << "Hello from " << vcl.getProcessUnitID() << " to " << p_id;
incardon's avatar
incardon committed
182
					std::string str(msg.str());
incardon's avatar
incardon committed
183
184
					message.last().resize(j);
					memset(message.last().getPointer(),0,j);
incardon's avatar
incardon committed
185
186
					std::copy(str.c_str(),&(str.c_str())[msg.str().size()],&(message.last().get(0)));
					// resize also recv_message
incardon's avatar
incardon committed
187
188
					recv_message.get(p_id).resize(j);
					memset(recv_message.get(p_id).getPointer(),0,j);
incardon's avatar
incardon committed
189
190
191
192
193
194
195
196
				}
			}

#ifdef VERBOSE_TEST
			timer t;
			t.start();
#endif

197
			recv_message.resize(n_proc);
incardon's avatar
incardon committed
198
199
200
201
202
			vcl.sendrecvMultipleMessages(prc,message,msg_alloc,&recv_message);

#ifdef VERBOSE_TEST
			t.stop();
			double clk = t.getwct();
incardon's avatar
incardon committed
203
			double clk_max = clk;
incardon's avatar
incardon committed
204

incardon's avatar
incardon committed
205
			size_t size_send_recv = 2 * j * (prc.size());
incardon's avatar
incardon committed
206
			vcl.reduce(size_send_recv);
incardon's avatar
incardon committed
207
			vcl.max(clk_max);
incardon's avatar
incardon committed
208
209
			vcl.execute();

incardon's avatar
incardon committed
210
			if (vcl.getProcessUnitID() == 0)
incardon's avatar
incardon committed
211
				std::cout << "(Short pattern: )Buffer size: " << j << "    Bandwidth (Average): " << size_send_recv / vcl.getProcessingUnits() / clk / 1e6 << " MB/s  " << "    Bandwidth (Total): " << size_send_recv / clk / 1e6 << " MB/s    Clock: " << clk << "   Clock MAX: " << clk_max <<"\n";
incardon's avatar
incardon committed
212
213
214
#endif

			// Check the message
215
			for (size_t i = 0 ; i < 8  && i < n_proc ; i++)
incardon's avatar
incardon committed
216
			{
217
218
219
220
221
222
223
				long int p_id = vcl.getProcessUnitID() - i - 1;
				if (p_id < 0)
					p_id += n_proc;
				else
					p_id = p_id % n_proc;

				if (p_id != vcl.getProcessUnitID())
incardon's avatar
incardon committed
224
225
				{
					std::ostringstream msg;
226
					msg << "Hello from " << p_id << " to " << vcl.getProcessUnitID();
incardon's avatar
incardon committed
227
					std::string str(msg.str());
228
					BOOST_REQUIRE_EQUAL(std::equal(str.c_str(),str.c_str() + str.size() ,&(recv_message.get(p_id).get(0))),true);
incardon's avatar
incardon committed
229
230
231
				}
				else
				{
232
					BOOST_REQUIRE_EQUAL(0,recv_message.get(p_id).size());
incardon's avatar
incardon committed
233
234
235
236
237
238
				}
			}
		}

		std::srand(global_v_cluster->getProcessUnitID());
		std::default_random_engine eg;
239
		std::uniform_int_distribution<int> d(0,n_proc/8);
incardon's avatar
incardon committed
240

incardon's avatar
incardon committed
241
		// Check random pattern (maximum 16 processors)
incardon's avatar
incardon committed
242

incardon's avatar
incardon committed
243
		for (size_t j = 32 ; j < N_LOOP && n_proc < 16 ; j*=2)
incardon's avatar
incardon committed
244
245
246
247
248
249
250
251
252
253
254
255
256
257
		{
			global_step = j;
			// original send
			openfpm::vector<size_t> o_send;
			// send message
			openfpm::vector<openfpm::vector<unsigned char>> message;
			// recv message
			openfpm::vector<openfpm::vector<unsigned char>> recv_message;

			openfpm::vector<size_t> prc;

			for (size_t i = 0 ; i < n_proc ; i++)
			{
				// randomly with witch processor communicate
258
				if (d(eg) == 0)
incardon's avatar
incardon committed
259
260
261
262
263
264
265
266
267
				{
					prc.add(i);
					o_send.add(i);
					message.add();
					std::ostringstream msg;
					msg << "Hello from " << vcl.getProcessUnitID() << " to " << i;
					std::string str(msg.str());
					message.last().resize(str.size());
					std::copy(str.c_str(),&(str.c_str())[msg.str().size()],&(message.last().get(0)));
incardon's avatar
incardon committed
268
					message.last().resize(j);
incardon's avatar
incardon committed
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
				}
			}

			id = 0;
			prc_recv.clear();


#ifdef VERBOSE_TEST
			timer t;
			t.start();
#endif

			vcl.sendrecvMultipleMessages(prc,message,msg_alloc2,&recv_message);

#ifdef VERBOSE_TEST
			t.stop();
			double clk = t.getwct();
incardon's avatar
incardon committed
286
			double clk_max = clk;
incardon's avatar
incardon committed
287

incardon's avatar
incardon committed
288
			size_t size_send_recv = (prc.size() + recv_message.size()) * j;
incardon's avatar
incardon committed
289
290
			vcl.reduce(size_send_recv);
			vcl.reduce(clk);
incardon's avatar
incardon committed
291
			vcl.max(clk_max);
incardon's avatar
incardon committed
292
293
294
			vcl.execute();
			clk /= vcl.getProcessingUnits();

incardon's avatar
incardon committed
295
			if (vcl.getProcessUnitID() == 0)
incardon's avatar
incardon committed
296
				std::cout << "(Random Pattern: ) Buffer size: " << j << "    Bandwidth (Average): " << size_send_recv / vcl.getProcessingUnits() / clk / 1e6 << " MB/s  " << "    Bandwidth (Total): " << size_send_recv / clk / 1e6 <<  " MB/s    Clock: " << clk << "   Clock MAX: " << clk_max << "\n";
incardon's avatar
incardon committed
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
#endif

			// Check the message

			for (size_t i = 0 ; i < recv_message.size() ; i++)
			{
				std::ostringstream msg;
				msg << "Hello from " << prc_recv.get(i) << " to " << vcl.getProcessUnitID();
				std::string str(msg.str());
				BOOST_REQUIRE_EQUAL(std::equal(str.c_str(),str.c_str() + str.size() ,&(recv_message.get(i).get(0))),true);
			}

			// Reply back

			// Create the message

			prc.clear();
			message.clear();
			for (size_t i = 0 ; i < prc_recv.size() ; i++)
			{
				prc.add(prc_recv.get(i));
				message.add();
				std::ostringstream msg;
				msg << "Hey from " << vcl.getProcessUnitID() << " to " << prc_recv.get(i);
				std::string str(msg.str());
				message.last().resize(str.size());
				std::copy(str.c_str(),&(str.c_str())[msg.str().size()],&(message.last().get(0)));
incardon's avatar
incardon committed
324
				message.last().resize(j);
incardon's avatar
incardon committed
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
			}

			id = 0;
			prc_recv.clear();
			recv_message.clear();
			vcl.sendrecvMultipleMessages(prc,message,msg_alloc2,&recv_message);

			// Check if the received hey message match the original send

			BOOST_REQUIRE_EQUAL(o_send.size(),prc_recv.size());

			for (size_t i = 0 ; i < o_send.size() ; i++)
			{
				size_t j = 0;
				for ( ; j < prc_recv.size() ; j++)
				{
					if (o_send.get(i) == prc_recv.get(j))
					{
						// found the message check it

						std::ostringstream msg;
						msg << "Hey from " << prc_recv.get(i) << " to " << vcl.getProcessUnitID();
						std::string str(msg.str());
						BOOST_REQUIRE_EQUAL(std::equal(str.c_str(),str.c_str() + str.size() ,&(recv_message.get(i).get(0))),true);
						break;
					}
				}
				// Check that we find always a match
				BOOST_REQUIRE_EQUAL(j != prc_recv.size(),true);
			}
		}
incardon's avatar
incardon committed
356
357
358
359
360
361
362

		// Check long communication pattern

		for (size_t j = 32 ; j < N_LOOP ; j*=2)
		{
			global_step = j;
			// Processor step
incardon's avatar
incardon committed
363
			size_t ps = n_proc / (8 + 1);
incardon's avatar
incardon committed
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

			// send message
			openfpm::vector<openfpm::vector<unsigned char>> message;
			// recv message
			openfpm::vector<openfpm::vector<unsigned char>> recv_message(n_proc);

			openfpm::vector<size_t> prc;

			for (size_t i = 0 ; i < 8  && i < n_proc ; i++)
			{
				size_t p_id = ((i+1) * ps + vcl.getProcessUnitID()) % n_proc;
				if (p_id != vcl.getProcessUnitID())
				{
					prc.add(p_id);
					message.add();
					std::ostringstream msg;
					msg << "Hello from " << vcl.getProcessUnitID() << " to " << p_id;
					std::string str(msg.str());
					message.last().resize(j);
					memset(message.last().getPointer(),0,j);
					std::copy(str.c_str(),&(str.c_str())[msg.str().size()],&(message.last().get(0)));
					// resize also recv_message
					recv_message.get(p_id).resize(j);
					memset(recv_message.get(p_id).getPointer(),0,j);
				}
			}

#ifdef VERBOSE_TEST
			timer t;
			t.start();
#endif

			recv_message.resize(n_proc);
			vcl.sendrecvMultipleMessages(prc,message,msg_alloc,&recv_message);

#ifdef VERBOSE_TEST
			t.stop();
			double clk = t.getwct();
			double clk_max = clk;

			size_t size_send_recv = 2 * j * (prc.size());
			vcl.reduce(size_send_recv);
			vcl.max(clk_max);
			vcl.execute();

			if (vcl.getProcessUnitID() == 0)
				std::cout << "(Long pattern: )Buffer size: " << j << "    Bandwidth (Average): " << size_send_recv / vcl.getProcessingUnits() / clk / 1e6 << " MB/s  " << "    Bandwidth (Total): " << size_send_recv / clk / 1e6 << " MB/s    Clock: " << clk << "   Clock MAX: " << clk_max <<"\n";
#endif

			// Check the message
			for (size_t i = 0 ; i < 8  && i < n_proc ; i++)
			{
incardon's avatar
incardon committed
416
				long int p_id = (- (i+1) * ps + vcl.getProcessUnitID()) % n_proc;
incardon's avatar
incardon committed
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
				if (p_id < 0)
					p_id += n_proc;
				else
					p_id = p_id % n_proc;

				if (p_id != vcl.getProcessUnitID())
				{
					std::ostringstream msg;
					msg << "Hello from " << p_id << " to " << vcl.getProcessUnitID();
					std::string str(msg.str());
					BOOST_REQUIRE_EQUAL(std::equal(str.c_str(),str.c_str() + str.size() ,&(recv_message.get(p_id).get(0))),true);
				}
				else
				{
					BOOST_REQUIRE_EQUAL(0,recv_message.get(p_id).size());
				}
			}
		}
incardon's avatar
incardon committed
435
436
437
438
439
440
441
442
443
	}

	std::cout << "VCluster unit test stop" << "\n";
}

BOOST_AUTO_TEST_SUITE_END()


#endif /* VCLUSTER_UNIT_TESTS_HPP_ */