1 #if COMPILATION_INSTRUCTIONS /* -*- indent-tabs-mode: t -*- */
2 mpic++ -O3 -D_TEST_BOOST_MPI3_VECTOR -xc++ $0 -o $0x -lboost_timer&&mpirun -np 1 $0x&&rm $0x;exit
3 #endif
4 #ifndef BOOST_MPI3_VECTOR_HPP
5 #define BOOST_MPI3_VECTOR_HPP
6
7 #include "../mpi3/allocator.hpp"
8
9 #include<mpi.h>
10
11 #include<vector>
12
13 namespace boost{
14 namespace mpi3{
15
16 template<class T>
17 using vector = std::vector<T, mpi3::allocator<T>>;
18
19 template<class T>
20 using uvector = std::vector<T, mpi3::uallocator<T>>;
21
22 //template<class T>
23 //struct uvector_iterator : std::vector<T, mpi3::uallocator<T>>{};
24
25 /*
26 template<class T>
27 struct uvector : std::vector<T, mpi3::uallocator<T>>{
28 using std::vector<T, mpi3::uallocator<T>>::vector;
29 uvector(std::vector<T> const& other)
30 : std::vector<T, mpi3::uallocator<T>>(reinterpret_cast<std::vector<T, mpi3::uallocator<T>>&>(other)){}
31 uvector(std::vector<T>&& other)
32 : std::vector<T, mpi3::uallocator<T>>(std::move(reinterpret_cast<std::vector<T, mpi3::uallocator<T>>&>(other))){}
33 operator std::vector<T>&&() &&{
34 return std::move(reinterpret_cast<std::vector<T>&>(*this));
35 }
36 operator std::vector<T>&() &{
37 return reinterpret_cast<std::vector<T>&>(*this);
38 }
39 operator std::vector<T> const&() const&{
40 return reinterpret_cast<std::vector<T> const&>(*this);
41 }
42
43 };*/
44
45 }}
46
47 #ifdef _TEST_BOOST_MPI3_VECTOR
48
49 #include <boost/timer/timer.hpp>
50
51 #include "../mpi3/main.hpp"
52 #include "../mpi3/detail/iterator.hpp"
53
54 using std::cout;
55 namespace mpi3 = boost::mpi3;
56
main(int,char * [],mpi3::communicator world)57 int mpi3::main(int, char*[], mpi3::communicator world){
58
59 mpi3::vector<long long> v(100);
60 std::iota(v.begin(), v.end(), 0);
61 assert( std::accumulate(v.begin(), v.end(), 0) == (v.size()*(v.size() - 1))/2 );
62
63 mpi3::uvector<std::size_t> uv(100);
64 // assert( std::accumulate(uv.begin(), uv.end(), 0) == 0 );
65
66 std::vector<std::size_t> v2(uv.begin(), uv.end());
67 assert(v2.size() == 100);
68 assert(uv.size() == 100);
69
70 std::vector<std::size_t> v3(uv.begin(), uv.end()); uv.clear();
71 assert(v3.size() == 100);
72 assert(uv.size() == 0);
73
74 using boost::timer::cpu_timer;
75 using boost::timer::cpu_times;
76
77 auto test_size = 100000000; // 100MB
78 cout << "test size " << test_size << " chars \n";
79 using vector = std::vector<char, mpi3::allocator<char>>;
80 cout << "std::vector<char, mpi3::allocator<char>> (pinned, initialized)\n";
81 {
82 cpu_timer t;
83 t.start();
84 cpu_times allocation_start = t.elapsed();
85 vector v(test_size);
86 cpu_times allocation_end = t.elapsed();
87 cpu_times firstuse_start = t.elapsed();
88 for(std::size_t i = 0; i != test_size; ++i) v[i] = 'l';
89 cpu_times firstuse_end = t.elapsed();
90 cpu_times seconduse_start = t.elapsed();
91 for(std::size_t i = 0; i != test_size; ++i) v[i] = 'z';
92 cpu_times seconduse_end = t.elapsed();
93 cout
94 << "\tallocation (+initialization if any) " << (allocation_end.wall - allocation_start.wall)/1.e6 << " milliseconds \n"
95 << "\tfirst use " << (firstuse_end.wall - firstuse_start.wall)/1.e6 << " milliseconds \n"
96 << "\tsecond use " << (seconduse_end.wall - seconduse_start.wall)/1.e6 << " milliseconds \n"
97 ;
98 }
99 /*
100 output:
101 test size 100000000 chars (mpic++ -O3)
102 std::vector<char> (no pinned, initialized)
103 allocation (+initialization if any) 33.3729 milliseconds
104 first use 4.78287 milliseconds
105 second use 6.60647 milliseconds
106
107 test size 100000000 chars
108 std::vector<char, mpi3::allocator<char>> (pinned, initialized)
109 allocation (+initialization if any) 0.006804 milliseconds
110 first use 31.1551 milliseconds
111 second use 4.82273 milliseconds
112
113 std::vector<char, mpi3::uallocator<char>> (pinned, uninitialized)
114 allocation (+initialization if any) 0.007946 milliseconds
115 first use 30.7246 milliseconds
116 second use 4.92651 milliseconds
117 */
118 return 0;
119 }
120
121 #endif
122 #endif
123
124