cuda-api-wrappers
Thin C++-flavored wrappers for the CUDA Runtime API
copy_parameters.hpp
Go to the documentation of this file.
1 
6 #ifndef CUDA_API_WRAPPERS_COPY_PARAMETERS_HPP
7 #define CUDA_API_WRAPPERS_COPY_PARAMETERS_HPP
8 
9 #include "array.hpp"
10 #include "pointer.hpp"
11 #include "constants.hpp"
12 #include "error.hpp"
13 
14 namespace cuda {
15 
16 namespace memory {
17 
19 enum class endpoint_t { source, destination };
20 
22 template<dimensionality_t NumDimensions>
23 struct copy_parameters_t;
25 
26 namespace detail_ {
27 
29 template<dimensionality_t NumDimensions>
30 struct base_copy_params;
31 
32 template<>
33 struct base_copy_params<2> {
34  using intra_context_type = CUDA_MEMCPY2D;
35  using type = intra_context_type; // Why is there no inter-context type, CUDA_MEMCPY2D_PEER ?
36 };
37 
38 template<>
39 struct base_copy_params<3> {
40  using type = CUDA_MEMCPY3D_PEER;
41  using intra_context_type = CUDA_MEMCPY3D;
42 };
43 
44 // Note these, by default, support inter-context
45 template<dimensionality_t NumDimensions>
46 using base_copy_params_t = typename base_copy_params<NumDimensions>::type;
47 
48 template<size_t NumDimensions>
50 non_array_endpoint_dimensions(endpoint_t endpoint, const copy_parameters_t<NumDimensions>& params);
51 
52 } //namespace detail_
53 
67 template<dimensionality_t NumDimensions>
68 struct copy_parameters_t : detail_::base_copy_params_t<NumDimensions> {
69  using parent = detail_::base_copy_params_t<NumDimensions>;
71  // TODO: Perhaps use proxies?
72 
75  using intra_context_type = typename detail_::base_copy_params<NumDimensions>::intra_context_type;
76 
78  using dimension_type = array::dimension_t;
79 
82  bool is_intra_context() const noexcept { return parent::srcContext == parent::dstContext; }
83 
85  this_type& set_context(endpoint_t endpoint, const context_t& context) noexcept;
86 
88  this_type& set_single_context(const context_t& context) noexcept
89  {
90  set_context(endpoint_t::source, context);
91  set_context(endpoint_t::destination, context);
92  return *this;
93  }
94 
100  template<typename T>
101  this_type& set_endpoint(endpoint_t endpoint, const cuda::array_t<T, NumDimensions> &array) noexcept;
102 
109  this_type& set_endpoint_untyped(
110  endpoint_t endpoint,
111  context::handle_t context_handle,
112  void *ptr,
113  dimensions_type dimensions);
114 
121  template<typename T>
123  this_type& set_endpoint(endpoint_t endpoint, T *ptr, dimensions_type dimensions);
124 
125  template<typename T>
126  this_type& set_endpoint(
127  endpoint_t endpoint,
128  context::handle_t context_handle,
129  T *ptr,
130  dimensions_type dimensions) noexcept;
132 
139  template<typename T>
140  this_type& set_endpoint(endpoint_t endpoint, span <T> span) noexcept
141  {
142  return set_endpoint(endpoint, span.data(), dimensions_type(span.size()));
143  }
144 
150  template<typename T>
152  {
153  return set_endpoint(endpoint_t::source, array);
154  }
155 
163  this_type& set_source_untyped(context::handle_t context_handle, void *ptr, dimensions_type dimensions)
164  {
165  return set_endpoint_untyped(endpoint_t::source, context_handle, ptr, dimensions);
166  }
167 
174  template<typename T>
176  this_type& set_source(T *ptr, dimensions_type dimensions) noexcept
177  {
178  return set_endpoint(endpoint_t::source, ptr, dimensions);
179  }
180 
181  template<typename T>
182  this_type& set_source(context::handle_t context_handle, T *ptr, dimensions_type dimensions) noexcept
183  {
184  return set_endpoint(endpoint_t::source, context_handle, ptr, dimensions);
185  }
187 
194  template<typename T>
195  this_type& set_source(span <T> span) noexcept
196  {
197  return set_source(span.data(), dimensions_type{span.size()});
198  }
199 
205  template<typename T>
207  {
208  return set_endpoint(endpoint_t::destination, array);
209  }
210 
219  context::handle_t context_handle,
220  void *ptr,
221  dimensions_type dimensions) noexcept
222  {
223  set_endpoint_untyped(endpoint_t::destination, context_handle, ptr, dimensions);
224  }
225 
232  template<typename T>
234  this_type& set_destination(T *ptr, dimensions_type dimensions) noexcept
235  {
236  return set_endpoint(endpoint_t::destination, ptr, dimensions);
237  }
238 
239  template<typename T>
240  this_type& set_destination(context::handle_t context_handle, T *ptr, dimensions_type dimensions) noexcept
241  {
242  return set_endpoint(endpoint_t::destination, context_handle, ptr, dimensions);
243  }
245 
252  template<typename T>
253  this_type& set_destination(span<T> span) noexcept
254  {
255  return set_destination(span.data(), {span.size(), 1, 1});
256  }
257 
260  this_type& set_bytes_offset(endpoint_t endpoint, dimensions_type offset) noexcept;
261 
264  template<typename T>
265  this_type& set_offset(endpoint_t endpoint, dimensions_type offset) noexcept;
266 
269  this_type& clear_offset(endpoint_t endpoint) noexcept
270  {
271  return set_bytes_offset(endpoint, dimensions_type::zero());
272  }
273 
276  {
277  clear_offset(endpoint_t::source);
278  clear_offset(endpoint_t::destination);
279  return *this;
280  }
281 
285  this_type& set_bytes_pitch(endpoint_t endpoint, dimension_type pitch_in_bytes) noexcept
286  {
287  (endpoint == endpoint_t::source ? parent::srcPitch : parent::dstPitch) = pitch_in_bytes;
288  return *this;
289  }
290 
294  template<typename T>
295  this_type& set_pitch(endpoint_t endpoint, dimension_type pitch_in_elements) noexcept
296  {
297  return set_bytes_pitch(endpoint, pitch_in_elements * sizeof(T));
298  }
299 
303  template<typename T>
304  this_type& set_pitches(dimension_type uniform_pitch_in_elements) noexcept
305  {
306  auto uniform_pitch_in_bytes { uniform_pitch_in_elements * sizeof(T) };
307  set_pitch<T>(endpoint_t::source, uniform_pitch_in_bytes);
308  set_pitch<T>(endpoint_t::destination, uniform_pitch_in_bytes);
309  return *this;
310  }
311 
312  // Note: Must be called after copy extents have been set
313  this_type& set_default_pitch(endpoint_t endpoint) noexcept
314  {
315  return set_bytes_pitch(endpoint, parent::WidthInBytes);
316  }
317 
318  // Note: Must be called after copy extents have been set
319  this_type& set_default_pitches() noexcept
320  {
321  set_default_pitch(endpoint_t::source);
322  set_default_pitch(endpoint_t::destination);
323  return *this;
324  }
325 
331  this_type& set_bytes_extent(dimensions_type extent_in_bytes) noexcept;
332 
338  template<typename T>
339  this_type& set_extent(dimensions_type extent_in_elements) noexcept;
340  // Sets how much is being copies, as opposed to the sizes of the endpoints which may be larger
341 
347  dimensions_type bytes_extent() const noexcept;
348 
354  template <typename T>
355  dimensions_type extent() const noexcept
356  {
357  auto extent_ = bytes_extent();
358 #ifndef NDEBUG
359  if (extent_.width % sizeof(T) != 0) {
360  throw ::std::invalid_argument(
361  "Attempt to get the copy extent with assumed type of size "
362  + ::std::to_string(sizeof(T)) + " while the byte extent's "
363  + "minor dimension is not a multiple of this size");
364  }
365 #endif
366  extent_.width /= sizeof(T);
367  return extent_;
368  }
369 
370  this_type& set_pitches(dimension_type uniform_pitch_in_bytes) noexcept
371  {
372  set_pitch(endpoint_t::source, uniform_pitch_in_bytes);
373  set_pitch(endpoint_t::destination, uniform_pitch_in_bytes);
374  return *this;
375  }
376 
377  this_type& clear_rest() noexcept;
378  // Clear any dummy fields which are required to be set to 0. Note that important fields,
379  // which you have not set explicitly, will _not_ be cleared by this method.
380 
381 };
382 
383 template<>
385  endpoint_t endpoint,
387  void * ptr,
388  array::dimensions_t<2> dimensions);
389 
390 template<>
392  endpoint_t endpoint,
394  void * ptr,
395  array::dimensions_t<3> dimensions);
396 
397 template<>
398 template<typename T>
400  endpoint_t endpoint,
401  context::handle_t context_handle,
402  T *ptr,
403  array::dimensions_t<2> dimensions) noexcept
404 {
405  array::dimensions_t<2> untyped_dims = {dimensions.width * sizeof(T), dimensions.height};
406  return set_endpoint_untyped(endpoint, context_handle, ptr, untyped_dims);
407 }
408 
409 template<>
410 template<typename T>
412  endpoint_t endpoint,
413  T *ptr,
414  array::dimensions_t<2> dimensions)
415 {
416  // We would have _liked_ to say:
417  // auto context_handle = context::current::detail_::get_handle();
418  // ... here, but alas, 2D copy structures don't support contexts, so...
419  auto context_handle = context::detail_::none;
420  return set_endpoint<T>(endpoint, context_handle, ptr, dimensions);
421 }
422 
423 template<>
424 template<typename T>
426 {
427  (endpoint == endpoint_t::source ? srcMemoryType : dstMemoryType) = CU_MEMORYTYPE_ARRAY;
428  (endpoint == endpoint_t::source ? srcArray : dstArray) = array.get();
429  (endpoint == endpoint_t::source ? srcDevice : dstDevice) = array.device_id();
430  // Can't set the endpoint context - the basic data structure doesn't support that!
431  return *this;
432 }
433 
434 namespace detail_ {
435 
436 template<>
437 inline array::dimensions_t<2> non_array_endpoint_dimensions<2>(endpoint_t endpoint, const copy_parameters_t<2>& params)
438 {
439  using dims_type = copy_parameters_t<2>::dimensions_type;
440  return (endpoint == endpoint_t::source) ?
441  dims_type{ params.WidthInBytes, params.Height } :
442  dims_type{ params.WidthInBytes, params.Height };
443 }
444 
445 template<>
446 inline array::dimensions_t<3> non_array_endpoint_dimensions<3>(endpoint_t endpoint, const copy_parameters_t<3>& params)
447 {
448  using dims_type = copy_parameters_t<3>::dimensions_type;
449  return (endpoint == endpoint_t::source) ?
450  dims_type{ params.srcPitch, params.Height, params.Depth } :
451  dims_type{ params.WidthInBytes, params.Height, params.Depth };
452 }
453 
454 } //
455 
456 template<>
457 template<typename T>
459 {
460  (endpoint == endpoint_t::source ? srcMemoryType : dstMemoryType) = CU_MEMORYTYPE_ARRAY;
461  (endpoint == endpoint_t::source ? srcArray : dstArray) = array.get();
462  (endpoint == endpoint_t::source ? srcContext : dstContext) = array.context_handle();
463  return *this;
464 }
465 
466 // 2D copy parameters only have an intra-context variant; should we silently assume the context
467 // is the same for both ends?
468 template<>
469 inline copy_parameters_t<2>& copy_parameters_t<2>::set_context(endpoint_t endpoint, const context_t& context) noexcept = delete;
470 
471 template<>
472 inline copy_parameters_t<3>& copy_parameters_t<3>::set_context(endpoint_t endpoint, const context_t& context) noexcept
473 {
474  (endpoint == endpoint_t::source ? srcContext : dstContext) = context.handle();
475  return *this;
476 }
477 
478 template<>
479 template<typename T>
481  endpoint_t endpoint,
482  context::handle_t context_handle,
483  T *ptr,
484  array::dimensions_t<3> dimensions) noexcept
485 {
486  array::dimensions_t<3> untyped_dims = {dimensions.width * sizeof(T), dimensions.height, dimensions.depth};
487  return set_endpoint_untyped(endpoint, context_handle, ptr, untyped_dims);
488 }
489 
490 template<>
491 template<typename T>
493  endpoint_t endpoint,
494  T *ptr,
495  array::dimensions_t<3> dimensions)
496 {
497  return set_endpoint<T>(endpoint, context::current::detail_::get_handle(), ptr, dimensions);
498 }
499 
500 template<>
502 {
503  return *this;
504 }
505 
506 template<>
508 {
509  srcLOD = 0;
510  dstLOD = 0;
511  return *this;
512 }
513 
514 template<>
515 template<typename T>
516 inline copy_parameters_t<2> &copy_parameters_t<2>::set_extent(dimensions_type extent_in_elements) noexcept
517 {
518  WidthInBytes = extent_in_elements.width * sizeof(T);
519  Height = extent_in_elements.height;
520  return *this;
521 }
522 
523 template<>
525 {
526  WidthInBytes = extent_in_elements.width;
527  Height = extent_in_elements.height;
528  return *this;
529 }
530 
531 template<>
533 {
534  WidthInBytes = extent_in_elements.width;
535  Height = extent_in_elements.height;
536  Depth = extent_in_elements.depth;
537  return *this;
538 }
539 
540 template<>
542 {
543  return copy_parameters_t<2>::dimensions_type { WidthInBytes, Height };
544 }
545 
546 template<>
548 {
549  return copy_parameters_t<3>::dimensions_type { WidthInBytes, Height, Depth };
550 }
551 
552 template<>
554  endpoint_t endpoint,
556  void * ptr,
557  array::dimensions_t<2> dimensions)
558 {
559  auto memory_type = memory::type_of(ptr);
560  if (memory_type == memory::type_t::array) {
561  throw ::std::invalid_argument("Attempt to use the non-array endpoint setter with array memory at " + cuda::detail_::ptr_as_hex(ptr));
562  }
563  if (memory_type == memory::type_t::unified_ or memory_type == type_t::device_)
564  {
565  (endpoint == endpoint_t::source ? srcDevice : dstDevice) = device::address(ptr);
566  }
567  else {
568  // Either memory::type_t::host or memory::type_t::non_cuda
569  if (endpoint == endpoint_t::source) { srcHost = ptr; }
570  else { dstHost = ptr; }
571  }
572  set_bytes_pitch(endpoint, dimensions.width);
573  (endpoint == endpoint_t::source ? srcMemoryType : dstMemoryType) = static_cast<CUmemorytype>
574  (memory_type == memory::type_t::non_cuda ? memory::type_t::host_ : memory_type);
575  // Can't set the endpoint context - the basic data structure doesn't support that!
576  // (endpoint == endpoint_t::source ? srcContext : dstContext) = context_handle;
577 
578  if (bytes_extent().area() == 0) {
579  set_bytes_extent(dimensions);
580  }
581  return *this;
582 }
583 
584 template<>
586  endpoint_t endpoint,
587  context::handle_t context_handle,
588  void * ptr,
589  array::dimensions_t<3> dimensions)
590 {
591  auto memory_type = memory::type_of(ptr);
592  if (memory_type == memory::type_t::array) {
593  throw ::std::invalid_argument("Attempt to use the non-array endpoint setter with array memory at " + cuda::detail_::ptr_as_hex(ptr));
594  }
595  if (memory_type == memory::type_t::unified_ or memory_type == type_t::device_)
596  {
597  (endpoint == endpoint_t::source ? srcDevice : dstDevice) = device::address(ptr);
598  }
599  else {
600  // Either memory::type_t::host or memory::type_t::non_cuda
601  if (endpoint == endpoint_t::source) { srcHost = ptr; }
602  else { dstHost = ptr; }
603  }
604  set_bytes_pitch(endpoint, dimensions.width);
605  (endpoint == endpoint_t::source ? srcHeight : dstHeight) = dimensions.height;
606  (endpoint == endpoint_t::source ? srcMemoryType : dstMemoryType) = static_cast<CUmemorytype>
607  (memory_type == memory::type_t::non_cuda ? memory::type_t::host_ : memory_type);
608  (endpoint == endpoint_t::source ? srcContext : dstContext) = context_handle;
609 
610  if (bytes_extent().volume() == 0) {
611  set_bytes_extent(dimensions);
612  }
613 
614  return *this;
615 }
616 
617 
618 template<>
619 template<typename T>
621 {
622  dimensions_type extent_in_bytes{
623  extent_in_elements.width * sizeof(T),
624  extent_in_elements.height,
625  extent_in_elements.depth
626  };
627  return set_bytes_extent(extent_in_bytes);
628 }
629 
630 template<>
631 inline copy_parameters_t<3>&
633 {
634  (endpoint == endpoint_t::source ? srcXInBytes : dstXInBytes) = offset.width;
635  (endpoint == endpoint_t::source ? srcY : dstY) = offset.height;
636  (endpoint == endpoint_t::source ? srcZ : dstZ) = offset.depth;
637  return *this;
638 }
639 
640 template<>
641 inline copy_parameters_t<2> &
643 {
644  (endpoint == endpoint_t::source ? srcXInBytes : dstXInBytes) = offset.width;
645  (endpoint == endpoint_t::source ? srcY : dstY) = offset.height;
646  return *this;
647 }
648 
649 template<>
650 template<typename T>
652 {
653  dimensions_type offset_in_bytes{offset.width * sizeof(T), offset.height, offset.depth};
654  return set_bytes_offset(endpoint, offset_in_bytes);
655 }
656 
657 template<>
658 template<typename T>
660 {
661  dimensions_type offset_in_bytes{offset.width * sizeof(T), offset.height};
662  return set_bytes_offset(endpoint, offset_in_bytes);
663 }
664 
666 inline as_intra_context_parameters(const copy_parameters_t<3>& params)
667 {
668  if (params.srcDevice != params.dstDevice) {
669  throw ::std::invalid_argument("Attempt to use inter-device copy parameters for an intra-context copy");
670  }
671  if (params.srcContext != params.dstContext) {
672  throw ::std::invalid_argument("Attempt to use inter-context copy parameters for an intra-context copy");
673  }
674 
675  // TODO: Use designated initializers in C++20
677 
678  result.srcXInBytes = params.srcXInBytes;
679  result.srcY = params.srcY;
680  result.srcZ = params.srcZ;
681  result.srcLOD = params.srcLOD;
682  result.srcMemoryType = params.srcMemoryType;
683  result.srcHost = params.srcHost;
684  result.srcDevice = params.srcDevice;
685  result.srcArray = params.srcArray;
686  result.reserved0 = nullptr; // srcContext
687  result.srcPitch = params.srcPitch;
688  result.srcHeight = params.srcHeight;
689 
690  result.dstXInBytes = params.dstXInBytes;
691  result.dstY = params.dstY;
692  result.dstZ = params.dstZ;
693  result.dstLOD = params.dstLOD;
694  result.dstMemoryType = params.dstMemoryType;
695  result.dstHost = params.dstHost;
696  result.dstDevice = params.dstDevice;
697  result.dstArray = params.dstArray;
698  result.reserved1 = nullptr;
699  result.dstPitch = params.dstPitch;
700  result.dstHeight = params.dstHeight;
701 
702  result.WidthInBytes = params.WidthInBytes;
703  result.Height = params.Height;
704  result.Depth = params.Depth;
705  return result;
706 }
707 
708 } //namespace memory
709 
710 } // namespace cuda
711 
712 #endif //CUDA_API_WRAPPERS_COPY_PARAMETERS_HPP
this_type & set_destination(const cuda::array_t< T, NumDimensions > &array) noexcept
Set the source endpoint of the copy operation to be a CUDA array.
Definition: copy_parameters.hpp:206
this_type & set_endpoint(endpoint_t endpoint, span< T > span) noexcept
Set one of the copy endpoints to a multi-dimensional elements, starting at the beginning of a span of...
Definition: copy_parameters.hpp:140
endpoint_t
Type for choosing between endpoints of copy operations.
Definition: copy_parameters.hpp:19
this_type & set_single_context(const context_t &context) noexcept
Set the same context for both endpoints of the copy operation.
Definition: copy_parameters.hpp:88
Wrapper class for a CUDA context.
Definition: context.hpp:244
this_type & set_source(const cuda::array_t< T, NumDimensions > &array) noexcept
Set the source endpoint of the copy operation to be a CUDA array.
Definition: copy_parameters.hpp:151
Definitions and functionality wrapping CUDA APIs.
Definition: array.hpp:22
this_type & set_endpoint_untyped(endpoint_t endpoint, context::handle_t context_handle, void *ptr, dimensions_type dimensions)
Set one of the copy endpoints to a multi-dimensional elements, with dimensions specified in bytes rat...
CUcontext handle_t
Raw CUDA driver handle for a context; see {context_t}.
Definition: types.hpp:878
this_type & clear_offsets() noexcept
Clear the offsets into both the source and the destination endpoint regions.
Definition: copy_parameters.hpp:275
dimension_t width
The three constituent individual dimensions, named.
Definition: types.hpp:112
Owning wrapper for CUDA 2D and 3D arrays.
Definition: array.hpp:29
this_type & set_context(endpoint_t endpoint, const context_t &context) noexcept
Set the context for one end of the copy operation.
Dimensions for 2D CUDA arrays.
Definition: types.hpp:159
memory::type_t type_of(const void *ptr)
Determine the type of memory at a given address vis-a-vis the CUDA ecosystem: Was it allocated by the...
Definition: pointer.hpp:112
Dimensions for 3D CUDA arrays.
Definition: types.hpp:109
void set_destination_untyped(context::handle_t context_handle, void *ptr, dimensions_type dimensions) noexcept
Set the destination of the copy operation to be a sequence of multi-dimensional elements, with dimensions specified in bytes rather than actual elements, starting somewhere in memory (in any CUDA memory space)
Definition: copy_parameters.hpp:218
dimension_t width
The two constituent individual dimensions, named; no "depth" for the 2D case.
Definition: types.hpp:162
dimensions_type extent() const noexcept
Definition: copy_parameters.hpp:355
dimensions_type bytes_extent() const noexcept
this_type & set_destination(T *ptr, dimensions_type dimensions) noexcept
Set one of the copy endpoints to a multi-dimensional elements, starting somewhere in memory (in any C...
Definition: copy_parameters.hpp:234
this_type & set_source(T *ptr, dimensions_type dimensions) noexcept
Set one of the copy endpoints to a multi-dimensional elements, starting somewhere in memory (in any C...
Definition: copy_parameters.hpp:176
Contains a proxy class for CUDA arrays - GPU memory with 2-D or 3-D locality and hardware support for...
this_type & set_extent(dimensions_type extent_in_elements) noexcept
Set how much is to be copied in each dimension - in elements.
this_type & set_offset(endpoint_t endpoint, dimensions_type offset) noexcept
Set the (multi-dimensional) offset, in elements, into multidimensional range of elements at one of th...
this_type & clear_offset(endpoint_t endpoint) noexcept
Set the copy operation to use the multi-dimensional region of the specified endpoint without skipping...
Definition: copy_parameters.hpp:269
A builder-ish subclass template around the basic 2D or 3D copy parameters which CUDA&#39;s complex copyin...
Definition: copy_parameters.hpp:68
this_type & set_bytes_offset(endpoint_t endpoint, dimensions_type offset) noexcept
Set the (multi-dimensional) offset, in bytes, into multidimensional range of elements at one of the e...
typename detail_::base_copy_params< NumDimensions >::intra_context_type intra_context_type
A Raw CUDA Driver API type punning the general copy parameters, which is used for copy operations wit...
Definition: copy_parameters.hpp:75
Facilities for exception-based handling of Runtime and Driver API errors, including a basic exception...
address_t address(const void *device_ptr) noexcept
Definition: types.hpp:682
size_t dimension_t
An individual dimension extent for an array.
Definition: types.hpp:94
A wrapper class for host and/or device pointers, allowing easy access to CUDA&#39;s pointer attributes...
this_type & set_destination(span< T > span) noexcept
Set the desintation of the copy operation to a range of multi-dimensional elements, starting at the beginning of a span of memory (in any CUDA memory space)
Definition: copy_parameters.hpp:253
Fundamental CUDA-related constants and enumerations, not dependent on any more complex abstractions...
bool is_intra_context() const noexcept
Definition: copy_parameters.hpp:82
this_type & set_endpoint(endpoint_t endpoint, const cuda::array_t< T, NumDimensions > &array) noexcept
Set one of the copy endpoints to a CUDA array.
this_type & set_source(span< T > span) noexcept
Set one of the copy endpoints to a multi-dimensional elements, starting at the beginning of a span of...
Definition: copy_parameters.hpp:195
this_type & set_pitches(dimension_type uniform_pitch_in_elements) noexcept
Set the difference, in elements, between the beginning of sequences of the minor-most dimension...
Definition: copy_parameters.hpp:304
this_type & set_source_untyped(context::handle_t context_handle, void *ptr, dimensions_type dimensions)
Set the source of the copy operation to be a sequence of multi-dimensional elements, with dimensions specified in bytes rather than actual elements, starting somewhere in memory (in any CUDA memory space)
Definition: copy_parameters.hpp:163
this_type & set_bytes_pitch(endpoint_t endpoint, dimension_type pitch_in_bytes) noexcept
Set the difference, in bytes, between the beginning of sequences of the minor-most dimension...
Definition: copy_parameters.hpp:285
this_type & set_pitch(endpoint_t endpoint, dimension_type pitch_in_elements) noexcept
Set the difference, in elements, between the beginning of sequences of the minor-most dimension...
Definition: copy_parameters.hpp:295
CUDA&#39;s array memory-objects are multi-dimensional; but their dimensions, or extents, are not the same as cuda::grid::dimensions_t ; they may be much larger in each axis.
Definition: types.hpp:105
void zero(void *start, size_t num_bytes, optional_ref< const stream_t > stream={})
Sets all bytes in a region of memory to 0 (zero)
Definition: memory.hpp:416
this_type & set_bytes_extent(dimensions_type extent_in_bytes) noexcept
Set how much is to be copied in each dimension - in bytes.