diff --git a/include/boost/compute/distributed/vector.hpp b/include/boost/compute/distributed/vector.hpp index 6328a8e40..4c064102d 100644 --- a/include/boost/compute/distributed/vector.hpp +++ b/include/boost/compute/distributed/vector.hpp @@ -211,7 +211,7 @@ class vector } /// Creates a new vector and copies the values from \p other. - vector(const vector &other, bool blocking = false) + explicit vector(const vector &other, bool blocking = false) : m_queue(other.m_queue), m_size(other.m_size) { @@ -230,24 +230,38 @@ class vector copy(other, m_queue, blocking); } else { - copy(other, other.get_queue(), m_queue, blocking); + command_queue other_queue = other.get_queue(); + copy(other, other_queue, m_queue); } } + /// Creates a new vector and copies the values from \p other + /// with \p queue. + template + vector(const vector &other, + bool blocking = false) + : m_queue(other.m_queue), + m_size(other.m_size) + { + allocate_memory(m_size); + copy(other, m_queue, blocking); + } + /// Creates a new vector and copies the values from \p other. template vector(const vector &other, command_queue &queue, bool blocking = false) : m_queue(queue), - m_size(other.m_size) + m_size(other.size()) { allocate_memory(m_size); - if(m_queue == other.m_queue) { + if(m_queue == other.get_queue()) { copy(other, m_queue, blocking); } else { - copy(other, other.get_queue(), m_queue, blocking); + command_queue other_queue = other.get_queue(); + copy(other, other_queue, m_queue); } } @@ -279,8 +293,8 @@ class vector template vector& operator=(const vector &other) { - m_queue = other.m_queue; - m_size = other.m_size; + m_queue = other.get_queue(); + m_size = other.size(); allocate_memory(m_size); copy(other, m_queue, false); return *this; @@ -490,7 +504,12 @@ class vector return m_data[n].get_buffer(); } - const command_queue& get_queue() const +// const command_queue& get_queue() const +// { +// return m_queue; +// } + + command_queue get_queue() const { return m_queue; } @@ -585,8 +604,9 @@ class vector // device -> device (copying distributed vector) // both vectors must have the same command_queue + template inline wait_list - copy_async(vector& other, command_queue &queue) + copy_async(const vector &other, command_queue &queue) { wait_list events; events.reserve(m_data.size()); @@ -606,8 +626,9 @@ class vector // device -> device (copying distributed vector) // both vectors must have the same command_queue + template inline void - copy(vector& other, command_queue &queue, bool blocking) + copy(const vector &other, command_queue &queue, bool blocking) { if(blocking) { copy_async(other, queue).wait(); @@ -617,62 +638,30 @@ class vector } // device -> device (copying distributed vector) - inline wait_list - copy_async(vector& other, command_queue &other_queue, command_queue &queue) + template + inline void + copy(const vector &other, + command_queue &other_queue, + command_queue &queue) { wait_list events; events.reserve(m_data.size()); - ::boost::compute::context other_part_context; - ::boost::compute::context part_context; - for(size_t i = 0; i < m_data.size(); i++) + std::vector host(other.size()); + typename std::vector::iterator host_iter = host.begin(); + for(size_t i = 0; i < other.parts(); i++) { - other_part_context = other.get_buffer(i).get_context(); - part_context = get_buffer(i).get_context(); - if(part_context == other_part_context) { - std::vector host(other.part_size(i)); - events.safe_insert( - ::boost::compute::copy_async( - other.begin(i), - other.end(i), - host.begin(), - other_queue.get(i) - ) - ); - events.safe_insert( - ::boost::compute::copy_async( - host.begin(), - host.end(), - begin(i), - queue.get(i) - ) - ); - } - else { - events.safe_insert( - ::boost::compute::copy_async( - other.begin(i), - other.end(i), - begin(i), - queue.get(i) - ) - ); - } - } - return events; - } - - // device -> device (copying distributed vector) - inline void - copy(vector& other, - command_queue &other_queue, - command_queue &queue, - bool blocking) - { - if(blocking) { - copy_async(other, other_queue, queue).wait(); - } else { - copy_async(other, other_queue, queue); + events.safe_insert( + ::boost::compute::copy_async( + other.begin(i), + other.end(i), + host_iter, + other_queue.get(i) + ) + ); + host_iter += other.part_size(i); } + events.wait(); + copy_async(host.begin(), host.end(), queue).wait(); } private: diff --git a/test/test_distributed_vector.cpp b/test/test_distributed_vector.cpp index 47253f682..7f2e5f3ef 100644 --- a/test/test_distributed_vector.cpp +++ b/test/test_distributed_vector.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -178,4 +179,72 @@ BOOST_AUTO_TEST_CASE(host_iterator_ctor) BOOST_CHECK_EQUAL(distributed_vector.front(), 1); } +BOOST_AUTO_TEST_CASE(copy_ctor) +{ + std::vector queues; + queues.push_back(queue); + queues.push_back(queue); + bc::distributed::command_queue distributed_queue1(queues); + queues.push_back(queue); + bc::distributed::command_queue distributed_queue2(queues); + + bc::int_ value = -1; + size_t size = 64; + + bc::distributed::vector distributed_vector( + size, value, distributed_queue1, true + ); + bc::distributed::vector distributed_vector_copy1( + distributed_vector, true + ); + bc::distributed::vector distributed_vector_copy2( + distributed_vector, distributed_queue2, true + ); + bc::distributed::vector< + bc::int_, + bc::distributed::default_weight_func, bc::pinned_allocator + > distributed_vector_copy3( + distributed_vector, distributed_queue2, true + ); + + for(size_t i = 0; i < distributed_vector.parts(); i++) + { + BOOST_CHECK( + bc::equal( + distributed_vector.begin(i), + distributed_vector.end(i), + bc::make_constant_iterator(value), + distributed_queue1.get(i) + ) + ); + BOOST_CHECK( + bc::equal( + distributed_vector_copy1.begin(i), + distributed_vector_copy1.end(i), + bc::make_constant_iterator(value), + distributed_queue1.get(i) + ) + ); + } + for(size_t i = 0; i < distributed_vector_copy2.parts(); i++) + { + BOOST_CHECK( + bc::equal( + distributed_vector_copy2.begin(i), + distributed_vector_copy2.end(i), + bc::make_constant_iterator(value), + distributed_queue2.get(i) + ) + ); + BOOST_CHECK( + bc::equal( + distributed_vector_copy3.begin(i), + distributed_vector_copy3.end(i), + bc::make_constant_iterator(value), + distributed_queue2.get(i) + ) + ); + } +} + BOOST_AUTO_TEST_SUITE_END()