Skip to content

Commit

Permalink
Rewrite operator<<(std::ostream, vex::vector) with mapped pointers
Browse files Browse the repository at this point in the history
Also introduce const version of vector::map().
This fixes #197
  • Loading branch information
ddemidov committed Mar 18, 2016
1 parent 65b5504 commit 33d6daf
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 12 deletions.
12 changes: 12 additions & 0 deletions vexcl/backend/compute/device_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ class device_vector {
);
}

mapped_array map(boost::compute::command_queue q) const {
return mapped_array(
static_cast<T*>(
q.enqueue_map_buffer(
buffer, CL_MAP_READ,
0, size() * sizeof(T)
)
),
buffer_unmapper(q, buffer)
);
}

cl_mem raw() const {
return buffer.get();
}
Expand Down
6 changes: 6 additions & 0 deletions vexcl/backend/cuda/device_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CUdeviceptr>(reinterpret_cast<size_t>(buffer.get()));
Expand Down
12 changes: 12 additions & 0 deletions vexcl/backend/opencl/device_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ class device_vector {
);
}

mapped_array map(const cl::CommandQueue &q) const {
return mapped_array(
static_cast<T*>(
q.enqueueMapBuffer(
buffer, CL_TRUE, CL_MAP_READ,
0, size() * sizeof(T)
)
),
buffer_unmapper(q, buffer)
);
}

cl_mem raw() const {
return buffer();
}
Expand Down
35 changes: 23 additions & 12 deletions vexcl/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>::mapped_array
map(unsigned d = 0) const {
return buf[d].map(queue[d]);
}

/// Copy assignment
const vector& operator=(const vector &x) {
if (&x != this)
Expand Down Expand Up @@ -1007,19 +1016,21 @@ std::ostream &operator<<(std::ostream &o, const vex::vector<T> &t) {
boost::io::ios_all_saver stream_state(o);
const size_t chunk = std::is_integral<T>::value ? 10 : 5;

std::vector<T> 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<T>::value)
o << " " << std::setw(6) << data[i];
else if (std::is_arithmetic<T>::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<T>::value)
o << " " << std::setw(6) << ptr[j];
else if (std::is_arithmetic<T>::value)
o << std::scientific << std::setw(14) << ptr[j];
else
o << " " << ptr[j];
}
}
return o << "\n}\n";
}
Expand Down

0 comments on commit 33d6daf

Please sign in to comment.