Skip to content

Commit

Permalink
Merge pull request #211 from krasznaa/ConstCopy-main-20221214
Browse files Browse the repository at this point in the history
Constant Copies, main branch (2022.12.14.)
  • Loading branch information
krasznaa authored Dec 14, 2022
2 parents 88008f5 + 2aee6f7 commit f8ba7eb
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 75 deletions.
9 changes: 6 additions & 3 deletions benchmarks/sycl/benchmark_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <vecmem/memory/sycl/device_memory_resource.hpp>
#include <vecmem/memory/sycl/host_memory_resource.hpp>
#include <vecmem/utils/sycl/copy.hpp>
#include <vecmem/utils/sycl/queue_wrapper.hpp>

// Common benchmark include(s).
#include "../common/make_jagged_sizes.hpp"
Expand All @@ -24,12 +25,14 @@

namespace vecmem::sycl::benchmark {

/// The queue that the VecMem objects should use
static queue_wrapper queue;
/// The (host) memory resource to use in the benchmark(s).
static host_memory_resource host_mr;
static host_memory_resource host_mr{queue};
/// The (device) memory resource to use in the benchmark(s).
static device_memory_resource device_mr;
static device_memory_resource device_mr{queue};
/// The copy object to use in the benchmark(s).
static copy sycl_copy;
static copy sycl_copy{queue};

/// Function benchmarking "unknown" host-to-device jagged vector copies
void jaggedVectorUnknownHtoDCopy(::benchmark::State& state) {
Expand Down
38 changes: 19 additions & 19 deletions core/include/vecmem/utils/copy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,34 +72,34 @@ class VECMEM_CORE_EXPORT copy {

/// Set up the internal state of a vector buffer correctly on a device
template <typename TYPE>
event_type setup(data::vector_view<TYPE> data);
event_type setup(data::vector_view<TYPE> data) const;

/// Set all bytes of the vector to some value
template <typename TYPE>
event_type memset(data::vector_view<TYPE> data, int value);
event_type memset(data::vector_view<TYPE> data, int value) const;

/// Copy a 1-dimensional vector to the specified memory resource
template <typename TYPE>
data::vector_buffer<std::remove_cv_t<TYPE>> to(
const data::vector_view<TYPE>& data, memory_resource& resource,
type::copy_type cptype = type::unknown);
type::copy_type cptype = type::unknown) const;

/// Copy a 1-dimensional vector's data between two existing memory blocks
template <typename TYPE1, typename TYPE2>
event_type operator()(const data::vector_view<TYPE1>& from,
data::vector_view<TYPE2> to,
type::copy_type cptype = type::unknown);
type::copy_type cptype = type::unknown) const;

/// Copy a 1-dimensional vector's data into a vector object
template <typename TYPE1, typename TYPE2, typename ALLOC>
event_type operator()(const data::vector_view<TYPE1>& from,
std::vector<TYPE2, ALLOC>& to,
type::copy_type cptype = type::unknown);
type::copy_type cptype = type::unknown) const;

/// Helper function for getting the size of a resizable 1D buffer
template <typename TYPE>
typename data::vector_view<TYPE>::size_type get_size(
const data::vector_view<TYPE>& data);
const data::vector_view<TYPE>& data) const;

/// @}

Expand All @@ -108,70 +108,70 @@ class VECMEM_CORE_EXPORT copy {

/// Copy the internal state of a jagged vector buffer to the target device
template <typename TYPE>
event_type setup(data::jagged_vector_view<TYPE> data);
event_type setup(data::jagged_vector_view<TYPE> data) const;

/// Set all bytes of the jagged vector to some value
template <typename TYPE>
event_type memset(data::jagged_vector_view<TYPE> data, int value);
event_type memset(data::jagged_vector_view<TYPE> data, int value) const;

/// Copy a jagged vector to the specified memory resource
template <typename TYPE>
data::jagged_vector_buffer<std::remove_cv_t<TYPE>> to(
const data::jagged_vector_view<TYPE>& data, memory_resource& resource,
memory_resource* host_access_resource = nullptr,
type::copy_type cptype = type::unknown);
type::copy_type cptype = type::unknown) const;

/// Copy a jagged vector's data between two existing allocations
template <typename TYPE1, typename TYPE2>
event_type operator()(const data::jagged_vector_view<TYPE1>& from,
data::jagged_vector_view<TYPE2> to,
type::copy_type cptype = type::unknown);
type::copy_type cptype = type::unknown) const;

/// Copy a jagged vector's data into a vector object
template <typename TYPE1, typename TYPE2, typename ALLOC1, typename ALLOC2>
event_type operator()(const data::jagged_vector_view<TYPE1>& from,
std::vector<std::vector<TYPE2, ALLOC2>, ALLOC1>& to,
type::copy_type cptype = type::unknown);
type::copy_type cptype = type::unknown) const;

/// Helper function for getting the sizes of a resizable jagged vector
template <typename TYPE>
std::vector<typename data::vector_view<TYPE>::size_type> get_sizes(
const data::jagged_vector_view<TYPE>& data);
const data::jagged_vector_view<TYPE>& data) const;

/// Helper function for setting the sizes of a resizable jagged vector
template <typename TYPE>
event_type set_sizes(
const std::vector<typename data::vector_view<TYPE>::size_type>& sizes,
data::jagged_vector_view<TYPE> data);
data::jagged_vector_view<TYPE> data) const;

/// @}

protected:
/// Perform a "low level" memory copy
virtual void do_copy(std::size_t size, const void* from, void* to,
type::copy_type cptype);
type::copy_type cptype) const;
/// Perform a "low level" memory filling operation
virtual void do_memset(std::size_t size, void* ptr, int value);
virtual void do_memset(std::size_t size, void* ptr, int value) const;
/// Create an event for synchronization
virtual event_type create_event();
virtual event_type create_event() const;

private:
/// Helper function performing the copy of a jagged array/vector
template <typename TYPE1, typename TYPE2>
void copy_views_impl(
const std::vector<typename data::vector_view<TYPE1>::size_type>& sizes,
const data::vector_view<TYPE1>* from, data::vector_view<TYPE2>* to,
type::copy_type cptype);
type::copy_type cptype) const;
/// Helper function performing the copy of a jagged array/vector
template <typename TYPE1, typename TYPE2>
void copy_views_contiguous_impl(
const std::vector<typename data::vector_view<TYPE1>::size_type>& sizes,
const data::vector_view<TYPE1>* from, data::vector_view<TYPE2>* to,
type::copy_type cptype);
type::copy_type cptype) const;
/// Helper function for getting the sizes of a jagged vector/buffer
template <typename TYPE>
std::vector<typename data::vector_view<TYPE>::size_type> get_sizes_impl(
const data::vector_view<TYPE>* data, std::size_t size);
const data::vector_view<TYPE>* data, std::size_t size) const;
/// Check if a vector of views occupy a contiguous block of memory
template <typename TYPE>
static bool is_contiguous(const data::vector_view<TYPE>* data,
Expand Down
33 changes: 17 additions & 16 deletions core/include/vecmem/utils/impl/copy.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
namespace vecmem {

template <typename TYPE>
copy::event_type copy::setup(data::vector_view<TYPE> data) {
copy::event_type copy::setup(data::vector_view<TYPE> data) const {

// Check if anything needs to be done.
if ((data.size_ptr() == nullptr) || (data.capacity() == 0)) {
Expand All @@ -43,7 +43,7 @@ copy::event_type copy::setup(data::vector_view<TYPE> data) {
}

template <typename TYPE>
copy::event_type copy::memset(data::vector_view<TYPE> data, int value) {
copy::event_type copy::memset(data::vector_view<TYPE> data, int value) const {

// Check if anything needs to be done.
if (data.capacity() == 0) {
Expand All @@ -62,7 +62,7 @@ copy::event_type copy::memset(data::vector_view<TYPE> data, int value) {
template <typename TYPE>
data::vector_buffer<std::remove_cv_t<TYPE>> copy::to(
const vecmem::data::vector_view<TYPE>& data, memory_resource& resource,
type::copy_type cptype) {
type::copy_type cptype) const {

// Set up the result buffer.
data::vector_buffer<std::remove_cv_t<TYPE>> result(
Expand All @@ -80,7 +80,7 @@ data::vector_buffer<std::remove_cv_t<TYPE>> copy::to(
template <typename TYPE1, typename TYPE2>
copy::event_type copy::operator()(const data::vector_view<TYPE1>& from_view,
data::vector_view<TYPE2> to_view,
type::copy_type cptype) {
type::copy_type cptype) const {

// The input and output types are allowed to be different, but only by
// const-ness.
Expand Down Expand Up @@ -118,7 +118,7 @@ copy::event_type copy::operator()(const data::vector_view<TYPE1>& from_view,
template <typename TYPE1, typename TYPE2, typename ALLOC>
copy::event_type copy::operator()(const data::vector_view<TYPE1>& from_view,
std::vector<TYPE2, ALLOC>& to_vec,
type::copy_type cptype) {
type::copy_type cptype) const {

// The input and output types are allowed to be different, but only by
// const-ness.
Expand All @@ -141,7 +141,7 @@ copy::event_type copy::operator()(const data::vector_view<TYPE1>& from_view,

template <typename TYPE>
typename data::vector_view<TYPE>::size_type copy::get_size(
const data::vector_view<TYPE>& data) {
const data::vector_view<TYPE>& data) const {

// Handle the simple case, when the view/buffer is not resizable.
if (data.size_ptr() == nullptr) {
Expand All @@ -164,7 +164,7 @@ typename data::vector_view<TYPE>::size_type copy::get_size(
}

template <typename TYPE>
copy::event_type copy::setup(data::jagged_vector_view<TYPE> data) {
copy::event_type copy::setup(data::jagged_vector_view<TYPE> data) const {

// Check if anything needs to be done.
if (data.size() == 0) {
Expand Down Expand Up @@ -200,7 +200,8 @@ copy::event_type copy::setup(data::jagged_vector_view<TYPE> data) {
}

template <typename TYPE>
copy::event_type copy::memset(data::jagged_vector_view<TYPE> data, int value) {
copy::event_type copy::memset(data::jagged_vector_view<TYPE> data,
int value) const {

// Use a very naive/expensive implementation.
for (std::size_t i = 0; i < data.size(); ++i) {
Expand All @@ -214,7 +215,7 @@ copy::event_type copy::memset(data::jagged_vector_view<TYPE> data, int value) {
template <typename TYPE>
data::jagged_vector_buffer<std::remove_cv_t<TYPE>> copy::to(
const data::jagged_vector_view<TYPE>& data, memory_resource& resource,
memory_resource* host_access_resource, type::copy_type cptype) {
memory_resource* host_access_resource, type::copy_type cptype) const {

// Create the result buffer object.
data::jagged_vector_buffer<std::remove_cv_t<TYPE>> result(
Expand All @@ -235,7 +236,7 @@ data::jagged_vector_buffer<std::remove_cv_t<TYPE>> copy::to(
template <typename TYPE1, typename TYPE2>
copy::event_type copy::operator()(
const data::jagged_vector_view<TYPE1>& from_view,
data::jagged_vector_view<TYPE2> to_view, type::copy_type cptype) {
data::jagged_vector_view<TYPE2> to_view, type::copy_type cptype) const {

// The input and output types are allowed to be different, but only by
// const-ness.
Expand Down Expand Up @@ -304,7 +305,7 @@ template <typename TYPE1, typename TYPE2, typename ALLOC1, typename ALLOC2>
copy::event_type copy::operator()(
const data::jagged_vector_view<TYPE1>& from_view,
std::vector<std::vector<TYPE2, ALLOC2>, ALLOC1>& to_vec,
type::copy_type cptype) {
type::copy_type cptype) const {

// The input and output types are allowed to be different, but only by
// const-ness.
Expand All @@ -327,7 +328,7 @@ copy::event_type copy::operator()(

template <typename TYPE>
std::vector<typename data::vector_view<TYPE>::size_type> copy::get_sizes(
const data::jagged_vector_view<TYPE>& data) {
const data::jagged_vector_view<TYPE>& data) const {

// Perform the operation using the private function.
return get_sizes_impl(data.host_ptr(), data.size());
Expand All @@ -336,7 +337,7 @@ std::vector<typename data::vector_view<TYPE>::size_type> copy::get_sizes(
template <typename TYPE>
copy::event_type copy::set_sizes(
const std::vector<typename data::vector_view<TYPE>::size_type>& sizes,
data::jagged_vector_view<TYPE> data) {
data::jagged_vector_view<TYPE> data) const {

// Finish early if possible.
if ((sizes.size() == 0) && (data.size() == 0)) {
Expand Down Expand Up @@ -380,7 +381,7 @@ template <typename TYPE1, typename TYPE2>
void copy::copy_views_impl(
const std::vector<typename data::vector_view<TYPE1>::size_type>& sizes,
const data::vector_view<TYPE1>* from_view,
data::vector_view<TYPE2>* to_view, type::copy_type cptype) {
data::vector_view<TYPE2>* to_view, type::copy_type cptype) const {

// The input and output types are allowed to be different, but only by
// const-ness.
Expand Down Expand Up @@ -427,7 +428,7 @@ template <typename TYPE1, typename TYPE2>
void copy::copy_views_contiguous_impl(
const std::vector<typename data::vector_view<TYPE1>::size_type>& sizes,
const data::vector_view<TYPE1>* from_view,
data::vector_view<TYPE2>* to_view, type::copy_type cptype) {
data::vector_view<TYPE2>* to_view, type::copy_type cptype) const {

// The input and output types are allowed to be different, but only by
// const-ness.
Expand Down Expand Up @@ -474,7 +475,7 @@ void copy::copy_views_contiguous_impl(

template <typename TYPE>
std::vector<typename data::vector_view<TYPE>::size_type> copy::get_sizes_impl(
const data::vector_view<TYPE>* data, std::size_t size) {
const data::vector_view<TYPE>* data, std::size_t size) const {

// Create the result vector.
std::vector<typename data::vector_view<TYPE>::size_type> result(size, 0);
Expand Down
6 changes: 3 additions & 3 deletions core/src/utils/copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct noop_event : public vecmem::abstract_event {
namespace vecmem {

void copy::do_copy(std::size_t size, const void* from_ptr, void* to_ptr,
type::copy_type) {
type::copy_type) const {

// Perform a simple POSIX memory copy.
::memcpy(to_ptr, from_ptr, size);
Expand All @@ -36,7 +36,7 @@ void copy::do_copy(std::size_t size, const void* from_ptr, void* to_ptr,
size, from_ptr, to_ptr);
}

void copy::do_memset(std::size_t size, void* ptr, int value) {
void copy::do_memset(std::size_t size, void* ptr, int value) const {

// Perform the POSIX memory setting operation.
::memset(ptr, value, size);
Expand All @@ -46,7 +46,7 @@ void copy::do_memset(std::size_t size, void* ptr, int value) {
value, ptr);
}

copy::event_type copy::create_event() {
copy::event_type copy::create_event() const {

// Make a no-op event.
return std::make_unique<noop_event>();
Expand Down
7 changes: 4 additions & 3 deletions cuda/include/vecmem/utils/cuda/async_copy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ class VECMEM_CUDA_EXPORT async_copy : public vecmem::copy {
protected:
/// Perform an asynchronous memory copy using CUDA
virtual void do_copy(std::size_t size, const void* from, void* to,
type::copy_type cptype) override;
type::copy_type cptype) const override;
/// Fill a memory area using CUDA asynchronously
virtual void do_memset(std::size_t size, void* ptr, int value) override;
virtual void do_memset(std::size_t size, void* ptr,
int value) const override;
/// Create an event for synchronization
virtual event_type create_event() override;
virtual event_type create_event() const override;

private:
/// The stream that the copies are performed on
Expand Down
5 changes: 3 additions & 2 deletions cuda/include/vecmem/utils/cuda/copy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ class VECMEM_CUDA_EXPORT copy : public vecmem::copy {
protected:
/// Perform a memory copy using CUDA
virtual void do_copy(std::size_t size, const void* from, void* to,
type::copy_type cptype) override;
type::copy_type cptype) const override;
/// Fill a memory area using CUDA
virtual void do_memset(std::size_t size, void* ptr, int value) override;
virtual void do_memset(std::size_t size, void* ptr,
int value) const override;

}; // class copy

Expand Down
6 changes: 3 additions & 3 deletions cuda/src/utils/cuda/async_copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static const std::string copy_type_printer[copy::type::count] = {
async_copy::async_copy(const stream_wrapper& stream) : m_stream(stream) {}

void async_copy::do_copy(std::size_t size, const void* from_ptr, void* to_ptr,
type::copy_type cptype) {
type::copy_type cptype) const {

// Check if anything needs to be done.
if (size == 0) {
Expand All @@ -84,7 +84,7 @@ void async_copy::do_copy(std::size_t size, const void* from_ptr, void* to_ptr,
copy_type_printer[cptype].c_str(), size, from_ptr, to_ptr);
}

void async_copy::do_memset(std::size_t size, void* ptr, int value) {
void async_copy::do_memset(std::size_t size, void* ptr, int value) const {

// Check if anything needs to be done.
if (size == 0) {
Expand All @@ -105,7 +105,7 @@ void async_copy::do_memset(std::size_t size, void* ptr, int value) {
size, value, ptr);
}

async_copy::event_type async_copy::create_event() {
async_copy::event_type async_copy::create_event() const {

// Create a CUDA event.
cudaEvent_t cudaEvent = nullptr;
Expand Down
4 changes: 2 additions & 2 deletions cuda/src/utils/cuda/copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static const std::string copy_type_printer[copy::type::count] = {
"unknown"};

void copy::do_copy(std::size_t size, const void* from_ptr, void* to_ptr,
type::copy_type cptype) {
type::copy_type cptype) const {

// Check if anything needs to be done.
if (size == 0) {
Expand All @@ -58,7 +58,7 @@ void copy::do_copy(std::size_t size, const void* from_ptr, void* to_ptr,
copy_type_printer[cptype].c_str(), size, from_ptr, to_ptr);
}

void copy::do_memset(std::size_t size, void* ptr, int value) {
void copy::do_memset(std::size_t size, void* ptr, int value) const {

// Check if anything needs to be done.
if (size == 0) {
Expand Down
Loading

0 comments on commit f8ba7eb

Please sign in to comment.