This source file includes following definitions.
- gen_bt_terminate
- __cxa_pure_virtual
- BOOST_AUTO_TEST_SUITE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "stdafx.h"
22
23 #define BOOST_TEST_MODULE libjmmcg_tests
24 #include <boost/test/included/unit_test.hpp>
25
26 #include <boost/test/test_case_template.hpp>
27 #include <boost/mpl/list.hpp>
28
29 #include "core/thread_pool_sequential.hpp"
30 #include "core/thread_pool_workers.hpp"
31
32 #include <boost/graph/graphviz.hpp>
33
34 #include <chrono>
35 #include <random>
36
37 using namespace jmmcg;
38 using namespace jmmcg::ppd;
39
40 using timed_results_t=ave_deviation_meter<double>;
41
42 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned long GSSk=1>
43 struct erew_normal_fifo_t {
44 typedef api_lock_traits<platform_api, Mdl> lock_traits;
45 typedef safe_colln<
46 std::vector<long>,
47 typename lock_traits::nonrecursive_anon_mutex_type
48 > vtr_colln_t;
49
50 typedef pool_aspects<
51 Jn,
52 platform_api,
53 Mdl,
54 pool_traits::normal_fifo,
55 std::less,
56 GSSk
57
58
59 > thread_pool_traits;
60
61 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
62
63 static constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
64 };
65
66 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned long GSSk=1>
67 struct erew_normal_lifo_t {
68 typedef api_lock_traits<platform_api, Mdl> lock_traits;
69 typedef safe_colln<
70 std::vector<long>,
71 typename lock_traits::nonrecursive_anon_mutex_type
72 > vtr_colln_t;
73
74 typedef pool_aspects<
75 Jn,
76 platform_api,
77 Mdl,
78 pool_traits::normal_lifo,
79 std::less,
80 GSSk
81
82
83 > thread_pool_traits;
84
85 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
86
87 static constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
88 };
89
90 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned long GSSk=1>
91 struct erew_priority_queue_t {
92 typedef api_lock_traits<platform_api, Mdl> lock_traits;
93 typedef safe_colln<
94 std::vector<long>,
95 typename lock_traits::nonrecursive_anon_mutex_type
96 > vtr_colln_t;
97
98 typedef pool_aspects<
99 Jn,
100 platform_api,
101 Mdl,
102 pool_traits::prioritised_queue,
103 std::less,
104 GSSk
105
106
107 > thread_pool_traits;
108
109 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
110
111 static constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
112 };
113
114 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned long GSSk=1UL>
115 struct crew_normal_fifo_t {
116 typedef api_lock_traits<platform_api, Mdl> lock_traits;
117 typedef safe_colln<
118 std::vector<long>,
119 typename lock::rw::locker<lock_traits>,
120 typename lock::rw::locker<lock_traits>::decaying_write_lock_type
121 > vtr_colln_t;
122
123 typedef pool_aspects<
124 Jn,
125 platform_api,
126 Mdl,
127 pool_traits::normal_fifo,
128 std::less,
129 GSSk
130
131
132 > thread_pool_traits;
133
134 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
135
136 static constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
137 };
138
139 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned long GSSk=1UL>
140 struct crew_normal_lifo_t {
141 typedef api_lock_traits<platform_api, Mdl> lock_traits;
142 typedef safe_colln<
143 std::vector<long>,
144 typename lock::rw::locker<lock_traits>,
145 typename lock::rw::locker<lock_traits>::decaying_write_lock_type
146 > vtr_colln_t;
147
148 typedef pool_aspects<
149 Jn,
150 platform_api,
151 Mdl,
152 pool_traits::normal_lifo,
153 std::less,
154 GSSk
155
156
157 > thread_pool_traits;
158
159 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
160
161 static constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
162 };
163
164 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned long GSSk=1UL>
165 struct crew_normal_lifo_lockfree_t {
166 typedef api_lock_traits<platform_api, Mdl> lock_traits;
167 typedef safe_colln<
168 std::vector<long>,
169 typename lock::rw::locker<lock_traits>,
170 typename lock::rw::locker<lock_traits>::decaying_write_lock_type
171 > vtr_colln_t;
172
173 typedef pool_aspects<
174 Jn,
175 platform_api,
176 Mdl,
177 pool_traits::normal_lifo_lockfree,
178 std::less,
179 GSSk
180
181
182 > thread_pool_traits;
183
184 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
185
186 static constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
187 };
188
189 template<class Db, pool_traits::size_mode_t Sz, generic_traits::return_data Jn, class Mdl, unsigned int PoolSize=0, unsigned long GSSk=1>
190 struct crew_priority_queue_t {
191 typedef api_lock_traits<platform_api, Mdl> lock_traits;
192 typedef safe_colln<
193 std::vector<long>,
194 typename lock::rw::locker<lock_traits>,
195 typename lock::rw::locker<lock_traits>::decaying_write_lock_type
196 > vtr_colln_t;
197
198 typedef pool_aspects<
199 Jn,
200 platform_api,
201 Mdl,
202 pool_traits::prioritised_queue,
203 std::less,
204 GSSk
205
206
207 > thread_pool_traits;
208
209 typedef thread_pool<Db, Sz, thread_pool_traits> pool_type;
210
211 static constexpr typename pool_type::pool_type::size_type pool_size=PoolSize;
212 };
213
214 typedef boost::mpl::list<
215 crew_normal_fifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode>,
216 crew_normal_fifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 1>,
217
218 crew_normal_fifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 2>,
219 crew_normal_fifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 4>,
220 crew_normal_fifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 8>,
221 crew_normal_fifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 12>
222 > finite_fifo_test_types;
223
224 typedef boost::mpl::list<
225 crew_normal_lifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::sequential, generic_traits::return_data::joinable, sequential_mode>,
226 crew_normal_lifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 1>,
227 crew_normal_lifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 2>,
228 crew_normal_lifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 4>,
229 crew_normal_lifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 8>,
230 crew_normal_lifo_t<pool_traits::work_distribution_mode_t::worker_threads_get_work<pool_traits::work_distribution_mode_t::queue_model_t::pool_owns_queue>, pool_traits::size_mode_t::fixed_size, generic_traits::return_data::joinable, heavyweight_threading, 12>
231
232
233 > finite_lifo_test_types;
234
235 void gen_bt_terminate() {
236 auto const &bt=api_threading_traits<platform_api, sequential_mode>::gen_backtrace();
237 std::cerr<<bt.begin()<<std::endl;
238 }
239
240 namespace __cxxabiv1 {
241 extern "C" void
242 __cxa_pure_virtual(void) {
243 gen_bt_terminate();
244 std::terminate();
245 }
246 }
247
248
249
250 BOOST_AUTO_TEST_SUITE(thread_pool_tests)
251
252 BOOST_AUTO_TEST_SUITE(joinable_dataflow)
253
254 BOOST_AUTO_TEST_SUITE(finite)
255
256 BOOST_AUTO_TEST_SUITE(n_elements)
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278 BOOST_AUTO_TEST_CASE_TEMPLATE(accumulate, T, finite_lifo_test_types) {
279 typedef typename T::vtr_colln_t vtr_colln_t;
280 typedef typename T::pool_type pool_type;
281
282 #ifdef JMMCG_PERFORMANCE_TESTS
283 const unsigned long test_size=2<<10;
284 const unsigned long num_reps=10000000;
285 #else
286 const unsigned long test_size=2<<3;
287 const unsigned long num_reps=2;
288 #endif
289 std::set_terminate(&gen_bt_terminate);
290 pool_type pool(T::pool_size);
291 std::cout<<"Pool="<<pool.pool_size()<<std::flush;
292 vtr_colln_t v;
293 v.reserve(test_size);
294 std::mt19937_64 gen(42);
295 std::uniform_int_distribution<typename vtr_colln_t::value_type> distribution(0, std::numeric_limits<typename vtr_colln_t::value_type>::max()/(test_size+1));
296 std::generate_n(std::back_inserter(v.colln()), test_size, std::bind(distribution, gen));
297 v.sync_size();
298 const typename vtr_colln_t::value_type res_chk=std::accumulate(v.colln().begin(), v.colln().end(), typename vtr_colln_t::value_type());
299 std::cout<<", items="<<v.size()<<std::flush;
300 const std::pair<timed_results_t, bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
301 10.0,
302 num_reps,
303 [&pool, res_chk, &v]() {
304 typedef typename pool_type::joinable joinable;
305
306 typename vtr_colln_t::value_type res;
307 const auto t1=std::chrono::high_resolution_clock::now();
308 auto const &context=pool<<joinable()<<pool.accumulate(v, typename vtr_colln_t::value_type());
309 res=*context;
310 const auto t2=std::chrono::high_resolution_clock::now();
311 BOOST_CHECK_EQUAL(res, res_chk);
312 return timed_results_t::value_type(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000;
313 }
314 ));
315 std::cout<<", time taken: "<<timed_results.first<<" sec."<<std::endl;
316 std::cout<<pool.statistics()<<std::endl;
317 std::ofstream ofs("accumulate.dot");
318 pool.cfg().write_graphviz(ofs);
319 #ifdef JMMCG_PERFORMANCE_TESTS
320
321 #endif
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337 BOOST_AUTO_TEST_CASE_TEMPLATE(merge, T, finite_lifo_test_types) {
338 typedef typename T::vtr_colln_t vtr_colln_t;
339 typedef typename T::pool_type pool_type;
340
341 #ifdef JMMCG_PERFORMANCE_TESTS
342 const unsigned long test_size=2<<25;
343 const unsigned long num_reps=2000;
344 #else
345 const unsigned long test_size=2<<3;
346 const unsigned long num_reps=2;
347 #endif
348 pool_type pool(T::pool_size);
349 std::cout<<"Pool="<<pool.pool_size()<<std::flush;
350 vtr_colln_t v, v1;
351 v.reserve(test_size);
352 v1.reserve(test_size);
353 std::mt19937_64 gen(42);
354 std::uniform_int_distribution<typename vtr_colln_t::value_type> distribution(0, std::numeric_limits<typename vtr_colln_t::value_type>::max()/test_size);
355 std::generate_n(std::back_inserter(v.colln()), test_size, std::bind(distribution, gen));
356 v.sync_size();
357 std::sort(v.colln().begin(), v.colln().end());
358 std::generate_n(std::back_inserter(v1.colln()), test_size, std::bind(distribution, gen));
359 v1.sync_size();
360 std::sort(v1.colln().begin(), v1.colln().end());
361 vtr_colln_t v_out;
362
363 v_out.colln().reserve(v.size()+v1.size());
364 v_out.resize_noinit_nolk(v.size()+v1.size());
365 vtr_colln_t v_chk;
366 v_chk.colln().reserve(v.size()+v1.size());
367 std::merge(v.colln().begin(), v.colln().end(), v1.colln().begin(), v1.colln().end(), std::back_inserter(v_chk.colln()));
368 v_chk.sync_size();
369 std::cout<<", items="<<(v.size()+v1.size())<<std::flush;
370 const std::pair<timed_results_t, bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
371 10.0,
372 num_reps,
373 [&pool, &v_chk, &v, &v1, &v_out]() {
374 typedef typename pool_type::joinable joinable;
375
376 typename vtr_colln_t::value_type res;
377 const auto t1=std::chrono::high_resolution_clock::now();
378 auto const &context=pool<<joinable()<<pool.merge(v, v1, v_out);
379 *context;
380 const auto t2=std::chrono::high_resolution_clock::now();
381 BOOST_CHECK_EQUAL(v_out.size(), v_chk.size());
382 BOOST_CHECK(v_out==v_chk);
383 return timed_results_t::value_type(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000;
384 }
385 ));
386 std::cout<<", time taken: "<<timed_results.first<<" sec."<<std::endl;
387 std::cout<<pool.statistics()<<std::endl;
388 std::ofstream ofs("merge.dot");
389 pool.cfg().write_graphviz(ofs);
390 #ifdef JMMCG_PERFORMANCE_TESTS
391 BOOST_CHECK(!timed_results.second);
392 #endif
393 }
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408 BOOST_AUTO_TEST_CASE_TEMPLATE(sort_unsorted, T, finite_lifo_test_types) {
409 typedef typename T::vtr_colln_t vtr_colln_t;
410 typedef typename T::pool_type pool_type;
411
412 #ifdef JMMCG_PERFORMANCE_TESTS
413 const unsigned long test_size=2<<25;
414 const unsigned long num_reps=2000;
415 #else
416 const unsigned long test_size=2<<3;
417 const unsigned long num_reps=2;
418 #endif
419 pool_type pool(T::pool_size);
420 std::cout<<"Pool="<<pool.pool_size()<<std::flush;
421 vtr_colln_t v;
422 v.reserve(test_size);
423 std::mt19937_64 gen(42);
424 std::uniform_int_distribution<typename vtr_colln_t::value_type> distribution(0, std::numeric_limits<typename vtr_colln_t::value_type>::max()/test_size);
425 std::generate_n(std::back_inserter(v.colln()), test_size, std::bind(distribution, gen));
426 vtr_colln_t v_chk(v);
427 v.sync_size();
428 v_chk.sync_size();
429 std::sort(v_chk.colln().begin(), v_chk.colln().end());
430 std::cout<<", items="<<v.size()<<std::flush;
431 const std::pair<timed_results_t, bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
432 10.0,
433 num_reps,
434 [&pool, &v_chk, &v]() {
435 typedef typename pool_type::joinable joinable;
436
437 typename vtr_colln_t::value_type res;
438 const auto t1=std::chrono::high_resolution_clock::now();
439 auto const &context=pool<<joinable()<<pool.sort(v);
440 *context;
441 const auto t2=std::chrono::high_resolution_clock::now();
442 BOOST_CHECK(v==v_chk);
443 return timed_results_t::value_type(std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count())/1000000;
444 }
445 ));
446 std::cout<<", time taken: "<<timed_results.first<<" sec."<<std::endl;
447 std::cout<<pool.statistics()<<std::endl;
448 std::ofstream ofs("sort.dot");
449 pool.cfg().write_graphviz(ofs);
450 #ifdef JMMCG_PERFORMANCE_TESTS
451 BOOST_CHECK(!timed_results.second);
452 #endif
453 }
454
455 BOOST_AUTO_TEST_SUITE_END()
456
457 BOOST_AUTO_TEST_SUITE_END()
458
459 BOOST_AUTO_TEST_SUITE_END()
460
461 BOOST_AUTO_TEST_SUITE_END()