10 #include <cuda_runtime.h>
36 void const*
const* srcs,
37 std::size_t
const* sizes,
41 #if CUDART_VERSION >= 13000
45 auto is_invalid = [&](std::size_t i) {
46 return dsts[i] ==
nullptr || srcs[i] ==
nullptr || sizes[i] == 0;
49 std::vector<void*> valid_dsts;
50 std::vector<void const*> valid_srcs;
51 std::vector<std::size_t> valid_sizes;
53 bool has_invalid =
false;
54 for (std::size_t i = 0; i < count; ++i) {
62 valid_dsts.reserve(count);
63 valid_srcs.reserve(count);
64 valid_sizes.reserve(count);
65 for (std::size_t i = 0; i < count; ++i) {
66 if (dsts[i] !=
nullptr && srcs[i] !=
nullptr && sizes[i] != 0) {
67 valid_dsts.push_back(dsts[i]);
68 valid_srcs.push_back(srcs[i]);
69 valid_sizes.push_back(sizes[i]);
72 if (valid_dsts.empty()) {
75 dsts = valid_dsts.data();
76 srcs = valid_srcs.data();
77 sizes = valid_sizes.data();
78 count = valid_dsts.size();
81 cudaMemcpyAttributes attrs = {
82 .srcAccessOrder = cudaMemcpySrcAccessOrderStream,
83 .flags = cudaMemcpyFlagPreferOverlapWithCompute
85 std::size_t attrs_idxs = 0;
86 return cudaMemcpyBatchAsync(
87 dsts, srcs, sizes, count, &attrs, &attrs_idxs, 1, stream.
value()
91 for (std::size_t i = 0; i < count; ++i) {
92 if (dsts[i] ==
nullptr || srcs[i] ==
nullptr || sizes[i] == 0) {
95 cudaError_t status = cudaMemcpyAsync(
96 dsts[i], srcs[i], sizes[i], cudaMemcpyDefault, stream.
value()
98 if (status != cudaSuccess) {
141 void const* src_ptr = src;
cudaStream_t value() const noexcept
bool is_default() const noexcept
RAPIDS Multi-Processor interfaces.
cudaError_t cuda_memcpy_batch_async(void *const *dsts, void const *const *srcs, std::size_t const *sizes, std::size_t count, rmm::cuda_stream_view stream)
Asynchronously copies a batch of buffers using the most efficient available API.
cudaError_t cuda_memcpy_async(void *dst, void const *src, std::size_t count, rmm::cuda_stream_view stream)
Asynchronously copies memory between host and/or device buffers.