From 33d6dafd61b91dda97e17e5af46674a9d592365c Mon Sep 17 00:00:00 2001 From: Denis Demidov Date: Fri, 18 Mar 2016 10:09:18 +0300 Subject: [PATCH] Rewrite operator<<(std::ostream, vex::vector) with mapped pointers Also introduce const version of vector::map(). This fixes #197 --- vexcl/backend/compute/device_vector.hpp | 12 +++++++++ vexcl/backend/cuda/device_vector.hpp | 6 +++++ vexcl/backend/opencl/device_vector.hpp | 12 +++++++++ vexcl/vector.hpp | 35 ++++++++++++++++--------- 4 files changed, 53 insertions(+), 12 deletions(-) diff --git a/vexcl/backend/compute/device_vector.hpp b/vexcl/backend/compute/device_vector.hpp index f8095e871..b1977c119 100644 --- a/vexcl/backend/compute/device_vector.hpp +++ b/vexcl/backend/compute/device_vector.hpp @@ -131,6 +131,18 @@ class device_vector { ); } + mapped_array map(boost::compute::command_queue q) const { + return mapped_array( + static_cast( + q.enqueue_map_buffer( + buffer, CL_MAP_READ, + 0, size() * sizeof(T) + ) + ), + buffer_unmapper(q, buffer) + ); + } + cl_mem raw() const { return buffer.get(); } diff --git a/vexcl/backend/cuda/device_vector.hpp b/vexcl/backend/cuda/device_vector.hpp index 7c91fe6fd..d8ef83a4b 100644 --- a/vexcl/backend/cuda/device_vector.hpp +++ b/vexcl/backend/cuda/device_vector.hpp @@ -171,6 +171,12 @@ class device_vector { return ptr; } + mapped_array map(const command_queue &q) const { + mapped_array ptr(new T[n], buffer_unmapper(q, *this)); + read(q, 0, n, ptr.get(), true); + return ptr; + } + /// Returns raw CUdeviceptr handle. CUdeviceptr raw() const { return static_cast(reinterpret_cast(buffer.get())); diff --git a/vexcl/backend/opencl/device_vector.hpp b/vexcl/backend/opencl/device_vector.hpp index 8f1e985d2..6b0bbd317 100644 --- a/vexcl/backend/opencl/device_vector.hpp +++ b/vexcl/backend/opencl/device_vector.hpp @@ -116,6 +116,18 @@ class device_vector { ); } + mapped_array map(const cl::CommandQueue &q) const { + return mapped_array( + static_cast( + q.enqueueMapBuffer( + buffer, CL_TRUE, CL_MAP_READ, + 0, size() * sizeof(T) + ) + ), + buffer_unmapper(q, buffer) + ); + } + cl_mem raw() const { return buffer(); } diff --git a/vexcl/vector.hpp b/vexcl/vector.hpp index fe3d16d46..2f6603cf2 100644 --- a/vexcl/vector.hpp +++ b/vexcl/vector.hpp @@ -626,6 +626,15 @@ class vector : public vector_terminal_expression { return buf[d].map(queue[d]); } + /// Maps vector part located on the given device to a host array. + /** + * This returns a smart pointer that will be unmapped automatically + * upon destruction */ + typename backend::device_vector::mapped_array + map(unsigned d = 0) const { + return buf[d].map(queue[d]); + } + /// Copy assignment const vector& operator=(const vector &x) { if (&x != this) @@ -1007,19 +1016,21 @@ std::ostream &operator<<(std::ostream &o, const vex::vector &t) { boost::io::ios_all_saver stream_state(o); const size_t chunk = std::is_integral::value ? 10 : 5; - std::vector data(t.size()); - copy(t, data); - o << "{" << std::setprecision(6); - for(size_t i = 0 ; i < data.size() ; i++) { - if (i % chunk == 0) o << "\n" << std::setw(6) << i << ":"; - - if (std::is_integral::value) - o << " " << std::setw(6) << data[i]; - else if (std::is_arithmetic::value) - o << std::scientific << std::setw(14) << data[i]; - else - o << " " << data[i]; + for(unsigned p = 0; p < t.nparts(); ++p) { + size_t ps = t.part_size(p); + auto ptr = t.map(p); + + for(size_t i = t.part_start(p), j = 0; j < ps; ++j, ++i) { + if (i % chunk == 0) o << "\n" << std::setw(6) << i << ":"; + + if (std::is_integral::value) + o << " " << std::setw(6) << ptr[j]; + else if (std::is_arithmetic::value) + o << std::scientific << std::setw(14) << ptr[j]; + else + o << " " << ptr[j]; + } } return o << "\n}\n"; }