예제 #1
0
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++;
        }
    }
}