/** * Test halmd::radix_sort on host. */ static void test_radix_sort_host(int count, int repeat) { std::vector<unsigned int> input = make_uniform_array(count); std::vector<unsigned int> result(input.begin(), input.end()); std::sort(result.begin(), result.end()); BOOST_TEST_MESSAGE( " " << count << " elements" ); BOOST_TEST_MESSAGE( " " << repeat << " iterations" ); halmd::accumulator<double> elapsed; for (int i = 0; i < repeat; ++i) { std::vector<unsigned int> output(input.begin(), input.end()); { halmd::scoped_timer<halmd::timer> t(elapsed); halmd::radix_sort(output.begin(), output.end()); } BOOST_CHECK_EQUAL_COLLECTIONS( output.begin() , output.end() , result.begin() , result.end() ); } BOOST_TEST_MESSAGE( " " << mean(elapsed) * 1e3 << " ± " << error_of_mean(elapsed) * 1e3 << " ms per iteration" ); }
static void test_iota( size_type count , size_type value , size_type repeat ) { BOOST_TEST_MESSAGE( " " << count << " elements with first value " << value ); BOOST_TEST_MESSAGE( " " << repeat << " iterations" ); halmd::accumulator<double> elapsed; for (size_type i = 0; i < repeat; ++i) { cuda::vector<size_type> g_output(count); cuda::memset(g_output.begin(), g_output.end(), 0); { halmd::scoped_timer<halmd::timer> t(elapsed); halmd::iota(g_output.begin(), g_output.end(), value); } cuda::host::vector<size_type> h_output(count); BOOST_CHECK( cuda::copy( g_output.begin() , g_output.end() , h_output.begin()) == h_output.end() ); BOOST_CHECK_EQUAL_COLLECTIONS( h_output.begin() , h_output.end() , boost::make_counting_iterator(value) , boost::make_counting_iterator(value + count) ); } BOOST_TEST_MESSAGE( " " << mean(elapsed) * 1e3 << " ± " << error_of_mean(elapsed) * 1e3 << " ms per iteration" ); }
static void test_ordered( unsigned int nparticle , unsigned int nspecies , unsigned int repeat ) { typedef typename test_suite_type::particle_type particle_type; typedef typename test_suite_type::particle_group_type particle_group_type; typedef typename particle_group_type::array_type array_type; typedef typename particle_group_type::size_type size_type; typedef typename test_suite_type::all_type all_type; BOOST_TEST_MESSAGE(" " << "all of " << nparticle << " particles"); BOOST_TEST_MESSAGE(" " << repeat << " iterations"); std::shared_ptr<particle_type> particle = std::make_shared<particle_type>(nparticle, nspecies); std::shared_ptr<particle_group_type> group = std::make_shared<all_type>(particle); { BOOST_CHECK_EQUAL( *group->size(), nparticle ); } halmd::cache<> size_cache = group->size(); halmd::cache<> ordered_cache = group->ordered(); halmd::accumulator<double> elapsed; for (size_type i = 0; i < repeat; ++i) { std::vector<size_type> reverse_tag = make_random_tag(nparticle); BOOST_CHECK( size_cache == group->size() ); BOOST_CHECK( ordered_cache == group->ordered() ); BOOST_CHECK( set_reverse_tag( *particle , reverse_tag.begin()) == reverse_tag.end() ); { halmd::scoped_timer<halmd::timer> t(elapsed); halmd::cache<array_type> const& ordered = group->ordered(); BOOST_CHECK( ordered_cache != ordered ); ordered_cache = ordered; } std::vector<size_type> ordered(nparticle); BOOST_CHECK( get_ordered( *group , ordered.begin()) == ordered.end() ); BOOST_CHECK_EQUAL_COLLECTIONS( ordered.begin() , ordered.end() , reverse_tag.begin() , reverse_tag.end() ); } BOOST_TEST_MESSAGE( " " << mean(elapsed) * 1e3 << " ± " << error_of_mean(elapsed) * 1e3 << " ms per iteration" ); }
/** * Test generation of permutation using halmd::radix_sort on GPU. */ static void test_permutation_gpu(int count, int repeat) { std::vector<unsigned int> input_key = make_uniform_array(count); cuda::vector<unsigned int> g_input_key(count); BOOST_CHECK( cuda::copy( input_key.begin() , input_key.end() , g_input_key.begin()) == g_input_key.end() ); std::vector<unsigned int> result(input_key.begin(), input_key.end()); std::sort(result.begin(), result.end()); std::vector<unsigned int> input_value(count); std::iota(input_value.begin(), input_value.end(), 0); cuda::vector<unsigned int> g_input_value(count); BOOST_CHECK( cuda::copy( input_value.begin() , input_value.end() , g_input_value.begin()) == g_input_value.end() ); BOOST_TEST_MESSAGE( " " << count << " elements" ); BOOST_TEST_MESSAGE( " " << repeat << " iterations" ); halmd::accumulator<double> elapsed; for (int i = 0; i < repeat; ++i) { cuda::vector<unsigned int> g_output_key(count); BOOST_CHECK( cuda::copy( g_input_key.begin() , g_input_key.end() , g_output_key.begin()) == g_output_key.end() ); cuda::vector<unsigned int> g_output_value(count); BOOST_CHECK( cuda::copy( g_input_value.begin() , g_input_value.end() , g_output_value.begin()) == g_output_value.end() ); { halmd::scoped_timer<halmd::timer> t(elapsed); BOOST_CHECK( halmd::radix_sort( g_output_key.begin() , g_output_key.end() , g_output_value.begin()) == g_output_value.end() ); } cuda::host::vector<unsigned int> h_output_key(count); BOOST_CHECK( cuda::copy( g_output_key.begin() , g_output_key.end() , h_output_key.begin()) == h_output_key.end() ); BOOST_CHECK_EQUAL_COLLECTIONS( h_output_key.begin() , h_output_key.end() , result.begin() , result.end() ); cuda::host::vector<unsigned int> h_output_value(count); BOOST_CHECK( cuda::copy( g_output_value.begin() , g_output_value.end() , h_output_value.begin()) == h_output_value.end() ); auto value_to_key = [&](unsigned int value) { return input_key[value]; }; BOOST_CHECK_EQUAL_COLLECTIONS( boost::make_transform_iterator(h_output_value.begin(), value_to_key) , boost::make_transform_iterator(h_output_value.end(), value_to_key) , result.begin() , result.end() ); } BOOST_TEST_MESSAGE( " " << mean(elapsed) * 1e3 << " ± " << error_of_mean(elapsed) * 1e3 << " ms per iteration" ); }