void bulk_test(hpx::lcos::spmd_block block, std::size_t height, std::size_t width, std::size_t local_height, std::size_t local_width, std::size_t local_leading_dimension, std::string in_name, std::string out_name) { using const_iterator = typename std::vector<double>::const_iterator; using vector_type = hpx::partitioned_vector<double>; using view_type = hpx::partitioned_vector_view<double, 2>; vector_type vector_in; vector_type vector_out; vector_in.connect_to(hpx::launch::sync, in_name); vector_out.connect_to(hpx::launch::sync, out_name); view_type in(block, vector_in.begin(), vector_in.end(), {height, width}); view_type out(block, vector_out.begin(), vector_out.end(), {height, width}); // Ensure that only one image is doing put operations if (block.this_image() == 0) { std::size_t idx = 0; // traverse all the indexed elements for (auto&& v : in) { std::vector<double> data(local_height * local_width); std::size_t local_idx = 0; for (double& d : data) { d = static_cast<double>(idx + local_idx++); } // Put operation v = std::move(data); idx++; } } block.sync_all(); // Outer Transpose operation for (std::size_t j = 0; j < width; j++) for (std::size_t i = 0; i < height; i++) { // Put operation out(j, i) = in(i, j); } block.sync_all(); // Inner Transpose operation for (auto& v : hpx::local_view(out)) { for (std::size_t jj = 0; jj < local_width - 1; jj++) for (std::size_t ii = jj + 1; ii < local_height; ii++) { std::swap(v[jj + ii * local_leading_dimension], v[ii + jj * local_leading_dimension]); } } block.sync_all(); // Test the result of the computation if (block.this_image() == 0) { int idx = 0; std::vector<double> result(local_height * local_width); for (std::size_t j = 0; j < width; j++) for (std::size_t i = 0; i < height; i++) { std::size_t local_idx = 0; for (double& r : result) { r = static_cast<double>(idx + local_idx++); } // transpose the guess result for (std::size_t jj = 0; jj < local_width - 1; jj++) for (std::size_t ii = jj + 1; ii < local_height; ii++) { std::swap(result[jj + ii * local_leading_dimension], result[ii + jj * local_leading_dimension]); } // It's a Get operation std::vector<double> value = (std::vector<double>) out(j, i); const_iterator it1 = result.begin(), it2 = value.begin(); const_iterator end1 = result.end(); for (; it1 != end1; ++it1, ++it2) { HPX_TEST_EQ(*it1, *it2); } idx++; } } }
void bulk_test( hpx::lcos::spmd_block block, std::size_t size_x, std::size_t size_y, std::size_t size_z, std::size_t elt_size, std::string vec_name) { using const_iterator = typename std::vector<double>::const_iterator; using vector_type = hpx::partitioned_vector<double>; using view_type = hpx::partitioned_vector_view<double,3>; using view_type_iterator = typename view_type::iterator; using const_view_type_iterator = typename view_type::const_iterator; vector_type my_vector; my_vector.connect_to(hpx::launch::sync, vec_name); view_type my_view(block, my_vector.begin(), my_vector.end(), {size_x,size_y,size_z}); int idx = 0; // Ensure that only one image is putting data into the different // partitions if(block.this_image() == 0) { // Traverse all the co-indexed elements for(auto i = my_view.begin(); i != my_view.end(); i++) { // It's a Put operation *i = std::vector<double>(elt_size,idx++); } auto left_it = my_view.begin(); auto right_it = my_view.cbegin(); // Note: Useless computation, since we assign segments to themselves for(; left_it != my_view.end(); left_it++, right_it++) { // Check that dereferencing iterator and const_iterator does not // retrieve the same type HPX_TEST(( !std::is_same<decltype(*left_it),decltype(*right_it)>::value)); // It's a Put operation *left_it = *right_it; } } block.sync_all(); if(block.this_image() == 0) { int idx = 0; for (std::size_t k = 0; k<size_z; k++) for (std::size_t j = 0; j<size_y; j++) for (std::size_t i = 0; i<size_x; i++) { std::vector<double> result(elt_size,idx); // It's a Get operation std::vector<double> value = (std::vector<double>)my_view(i,j,k); const_iterator it1 = result.begin(), it2 = value.begin(); const_iterator end1 = result.end(); for (; it1 != end1; ++it1, ++it2) { HPX_TEST_EQ(*it1, *it2); } idx++; } idx = 0; // Re-check by traversing all the co-indexed elements for(auto i = my_view.cbegin(); i != my_view.cend(); i++) { std::vector<double> result(elt_size,idx); // It's a Get operation std::vector<double> value = (std::vector<double>)(*i); const_iterator it1 = result.begin(), it2 = value.begin(); const_iterator end1 = result.end(); for (; it1 != end1; ++it1, ++it2) { HPX_TEST_EQ(*it1, *it2); } idx++; } } }