void operator()(int tid) const { for (int j = tid; j < N; j+=my_num_threads) { T v; spin_try_get( my_q, v ); my_touches.check( tid, v ); } }
void operator()(int) const { for (int j = 0; j < N; ++j) { T v; spin_try_get( my_b, v ); my_touches.check( v ); } }
int test_parallel(int num_threads) { tbb::flow::graph g; tbb::flow::sequencer_node<T> s(g, seq_inspector<T>()); NativeParallelFor( num_threads, parallel_puts<T>(s, num_threads) ); { touches<T> t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(s, num_threads, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } T bogus_value(-1); T j = bogus_value; ASSERT( s.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); tbb::flow::sequencer_node<T> s1(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s2(g, seq_inspector<T>()); tbb::flow::sequencer_node<T> s3(g, seq_inspector<T>()); tbb::flow::make_edge( s1, s2 ); tbb::flow::make_edge( s2, s3 ); { touches<T> t( num_threads ); tbb::atomic<int> counter; counter = 0; NativeParallelFor( num_threads, parallel_put_get<T>(s1, s3, num_threads, counter, t) ); g.wait_for_all(); t.validate_touches(); } g.wait_for_all(); ASSERT( s1.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( s2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( s3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // test copy constructor tbb::flow::sequencer_node<T> s_copy(s); NativeParallelFor( num_threads, parallel_puts<T>(s_copy, num_threads) ); for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( s_copy, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( s_copy.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); return 0; }
void operator()(int tid) const { for ( int i = 0; i < N; i+=C ) { int j_end = ( N < i + C ) ? N : i + C; // dump about C values into the buffer for ( int j = i; j < j_end; ++j ) { ASSERT( my_b.try_put( T (N*tid + j ) ) == true, NULL ); } // receiver about C values from the buffer for ( int j = i; j < j_end; ++j ) { T v; spin_try_get( my_b, v ); my_touches.check( v ); } } }
void operator()(int tid) const { int i_start = 0; while ( (i_start = my_counter.fetch_and_add(C)) < N ) { int i_end = ( N < i_start + C ) ? N : i_start + C; for (int i = i_start; i < i_end; ++i) { bool msg = my_s1.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = i_start; i < i_end; ++i) { T v; spin_try_get( my_s2, v ); my_touches.check( tid, v ); } } }
int test_serial() { tbb::graph g; T bogus_value(-1); tbb::buffer_node<T> b(g); tbb::buffer_node<T> b2(g); T j = bogus_value; // // Rejects attempts to add / remove predecessor // Rejects request from empty buffer // ASSERT( b.register_predecessor( b2 ) == false, NULL ); ASSERT( b.remove_predecessor( b2 ) == false, NULL ); ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Simple puts and gets // for (int i = 0; i < N; ++i) { bool msg = b.try_put( T(i) ); ASSERT( msg == true, NULL ); } T vsum = T(0); for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( b, j ); vsum += j; } ASSERT( vsum == (N*(N-1))/2, NULL); j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.register_successor( b2 ) == true, NULL ); vsum = T(0); for (int i = 0; i < N; ++i) { bool msg = b.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( b2, j ); vsum += j; } ASSERT( vsum == (N*(N-1))/2, NULL); j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.remove_successor( b2 ) == true, NULL ); ASSERT( b.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( b.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); tbb::buffer_node<T> b3(g); ASSERT( b.register_successor( b2 ) == true, NULL ); ASSERT( b2.register_successor( b3 ) == true, NULL ); vsum = T(0); for (int i = 0; i < N; ++i) { bool msg = b.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( b3, j ); vsum += j; } ASSERT( vsum == (N*(N-1))/2, NULL); j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.remove_successor( b2 ) == true, NULL ); ASSERT( b.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( b3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( b.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); return 0; }
int test_parallel(int num_threads) { tbb::graph g; tbb::buffer_node<T> b(g); tbb::buffer_node<T> b2(g); tbb::buffer_node<T> b3(g); T bogus_value(-1); T j = bogus_value; NativeParallelFor( num_threads, parallel_puts<T>(b) ); T *next_value = new T[num_threads]; for (int tid = 0; tid < num_threads; ++tid) next_value[tid] = T(0); for (int i = 0; i < num_threads * N; ++i ) { spin_try_get( b, j ); check_item( next_value, j ); j = bogus_value; } for (int tid = 0; tid < num_threads; ++tid) { ASSERT( next_value[tid] == T((N*(N-1))/2), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(b) ); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(b, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_put_get<T>(b, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; ASSERT( b.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( b.register_successor( b2 ) == true, NULL ); ASSERT( b2.register_successor( b3 ) == true, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(b) ); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(b3, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( b.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( b3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); return 0; }
int test_serial() { tbb::graph g; T bogus_value(-1); tbb::queue_node<T> q(g); tbb::queue_node<T> q2(g); T j = bogus_value; // // Rejects attempts to add / remove predecessor // Rejects request from empty Q // ASSERT( q.register_predecessor( q2 ) == false, NULL ); ASSERT( q.remove_predecessor( q2 ) == false, NULL ); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Simple puts and gets // for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.register_successor( q2 ) == true, NULL ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q2, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.remove_successor( q2 ) == true, NULL ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); tbb::queue_node<T> q3(g); ASSERT( q.register_successor( q2 ) == true, NULL ); ASSERT( q2.register_successor( q3 ) == true, NULL ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q3, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.remove_successor( q2 ) == true, NULL ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); return 0; }
int test_parallel(int num_threads) { tbb::graph g; tbb::queue_node<T> q(g); tbb::queue_node<T> q2(g); tbb::queue_node<T> q3(g); T bogus_value(-1); T j = bogus_value; NativeParallelFor( num_threads, parallel_puts<T>(q) ); T *next_value = new T[num_threads]; for (int tid = 0; tid < num_threads; ++tid) next_value[tid] = T(0); for (int i = 0; i < num_threads * N; ++i ) { spin_try_get( q, j ); check_item( next_value, j ); j = bogus_value; } for (int tid = 0; tid < num_threads; ++tid) { ASSERT( next_value[tid] == T(N), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(q) ); { touches< T > t( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(q, t) ); g.wait_for_all(); ASSERT( t.validate_touches(), NULL ); } j = bogus_value; ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); { touches< T > t2( num_threads ); NativeParallelFor( num_threads, parallel_put_get<T>(q, t2) ); g.wait_for_all(); ASSERT( t2.validate_touches(), NULL ); } j = bogus_value; ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); ASSERT( q.register_successor( q2 ) == true, NULL ); ASSERT( q2.register_successor( q3 ) == true, NULL ); NativeParallelFor( num_threads, parallel_puts<T>(q) ); { touches< T > t3( num_threads ); NativeParallelFor( num_threads, parallel_gets<T>(q3, t3) ); g.wait_for_all(); ASSERT( t3.validate_touches(), NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); return 0; }
int test_serial() { tbb::flow::graph g; tbb::flow::queue_node<T> q(g); tbb::flow::queue_node<T> q2(g); { // destroy the graph after manipulating it, and see if all the items in the buffers // have been destroyed before the graph Check<T> my_check; // if check_type< U > count constructions and destructions T bogus_value(-1); T j = bogus_value; // // Rejects attempts to add / remove predecessor // Rejects request from empty Q // ASSERT( q.register_predecessor( q2 ) == false, NULL ); ASSERT( q.remove_predecessor( q2 ) == false, NULL ); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); // // Simple puts and gets // for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); tbb::flow::make_edge( q, q2 ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q2, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); tbb::flow::remove_edge( q, q2 ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); tbb::flow::queue_node<T> q3(g); tbb::flow::make_edge( q, q2 ); tbb::flow::make_edge( q2, q3 ); for (int i = 0; i < N; ++i) { bool msg = q.try_put( T(i) ); ASSERT( msg == true, NULL ); } for (int i = 0; i < N; ++i) { j = bogus_value; spin_try_get( q3, j ); ASSERT( i == j, NULL ); } j = bogus_value; g.wait_for_all(); ASSERT( q.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); tbb::flow::remove_edge( q, q2 ); ASSERT( q.try_put( 1 ) == true, NULL ); g.wait_for_all(); ASSERT( q2.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q3.try_get( j ) == false, NULL ); ASSERT( j == bogus_value, NULL ); g.wait_for_all(); ASSERT( q.try_get( j ) == true, NULL ); ASSERT( j == 1, NULL ); } return 0; }