Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
HostSpecificMemoryCopy.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* HostSpecificMemoryCopy.h (C) 2000-2026 */
9/* */
10/* Template class to manage specialized memory copy functions. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_COMMON_INTERNAL_HOSTSPECIFICMEMORYCOPYLIST_H
13#define ARCCORE_COMMON_INTERNAL_HOSTSPECIFICMEMORYCOPYLIST_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arccore/common/internal/SpecificMemoryCopyList.h"
18
19/*---------------------------------------------------------------------------*/
20/*---------------------------------------------------------------------------*/
21
22namespace Arcane::Impl
23{
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
31template <typename DataType, typename Extent>
33: public SpecificMemoryCopyBase<DataType, Extent>
34{
36 using BaseClass::_toTrueType;
37
38 public:
39
40 using BaseClass::m_extent;
41
42 public:
43
44 void copyFrom(const IndexedMemoryCopyArgs& args) override
45 {
46 _copyFrom(args.m_indexes, _toTrueType(args.m_source), _toTrueType(args.m_destination));
47 }
48 void copyTo(const IndexedMemoryCopyArgs& args) override
49 {
50 _copyTo(args.m_indexes, _toTrueType(args.m_source), _toTrueType(args.m_destination));
51 }
52 void fill(const IndexedMemoryCopyArgs& args) override
53 {
54 _fill(args.m_indexes, _toTrueType(args.m_source), _toTrueType(args.m_destination));
55 }
56 void copyFrom(const IndexedMultiMemoryCopyArgs& args) override
57 {
58 _copyFrom(args.m_indexes, args.m_multi_memory, _toTrueType(args.m_source_buffer));
59 }
60 void copyTo(const IndexedMultiMemoryCopyArgs& args) override
61 {
62 _copyTo(args.m_indexes, args.m_const_multi_memory, _toTrueType(args.m_destination_buffer));
63 }
64 void fill(const IndexedMultiMemoryCopyArgs& args) override
65 {
66 _fill(args.m_indexes, args.m_multi_memory, _toTrueType(args.m_source_buffer));
67 }
68
69 public:
70
71 void _copyFrom(SmallSpan<const Int32> indexes, Span<const DataType> source,
72 Span<DataType> destination)
73 {
74 ARCCORE_CHECK_POINTER(indexes.data());
75 ARCCORE_CHECK_POINTER(source.data());
76 ARCCORE_CHECK_POINTER(destination.data());
77
78 Int32 nb_index = indexes.size();
79 for (Int32 i = 0; i < nb_index; ++i) {
80 Int64 z_index = (Int64)i * m_extent.v;
81 Int64 zci = (Int64)(indexes[i]) * m_extent.v;
82 for (Int32 z = 0, n = m_extent.v; z < n; ++z)
83 destination[z_index + z] = source[zci + z];
84 }
85 }
86 void _copyFrom(SmallSpan<const Int32> indexes, SmallSpan<Span<std::byte>> multi_views,
88 {
89 ARCCORE_CHECK_POINTER(indexes.data());
90 ARCCORE_CHECK_POINTER(source.data());
91 ARCCORE_CHECK_POINTER(multi_views.data());
92
93 const Int32 value_size = indexes.size() / 2;
94 for (Int32 i = 0; i < value_size; ++i) {
95 Int32 index0 = indexes[i * 2];
96 Int32 index1 = indexes[(i * 2) + 1];
97 Span<std::byte> orig_view_bytes = multi_views[index0];
98 auto* orig_view_data = reinterpret_cast<DataType*>(orig_view_bytes.data());
99 // Uses a span to test array overflows but // could directly use
100 // 'orig_view_data' for better performance
101 Span<DataType> orig_view = { orig_view_data, orig_view_bytes.size() / (Int64)sizeof(DataType) };
102 Int64 zci = ((Int64)(index1)) * m_extent.v;
103 Int64 z_index = (Int64)i * m_extent.v;
104 for (Int32 z = 0, n = m_extent.v; z < n; ++z)
105 orig_view[zci + z] = source[z_index + z];
106 }
107 }
108
115 Span<DataType> destination)
116 {
117 ARCCORE_CHECK_POINTER(source.data());
118 ARCCORE_CHECK_POINTER(destination.data());
119
120 // If \a indexes is empty, it means all values are copied
121 Int32 nb_index = indexes.size();
122 if (nb_index == 0) {
123 Int64 nb_value = destination.size() / m_extent.v;
124 for (Int64 i = 0; i < nb_value; ++i) {
125 Int64 zci = i * m_extent.v;
126 for (Int32 z = 0, n = m_extent.v; z < n; ++z)
127 destination[zci + z] = source[z];
128 }
129 }
130 else {
131 ARCCORE_CHECK_POINTER(indexes.data());
132 for (Int32 i = 0; i < nb_index; ++i) {
133 Int64 zci = (Int64)(indexes[i]) * m_extent.v;
134 for (Int32 z = 0, n = m_extent.v; z < n; ++z)
135 destination[zci + z] = source[z];
136 }
137 }
138 }
139
140 void _fill(SmallSpan<const Int32> indexes, SmallSpan<Span<std::byte>> multi_views,
142 {
143 ARCCORE_CHECK_POINTER(source.data());
144 ARCCORE_CHECK_POINTER(multi_views.data());
145
146 const Int32 nb_index = indexes.size() / 2;
147 if (nb_index == 0) {
148 // Fills all values of the array with the source.
149 const Int32 nb_dim1 = multi_views.size();
150 for (Int32 zz = 0; zz < nb_dim1; ++zz) {
151 Span<std::byte> orig_view_bytes = multi_views[zz];
152 Int64 nb_value = orig_view_bytes.size() / ((Int64)sizeof(DataType));
153 auto* orig_view_data = reinterpret_cast<DataType*>(orig_view_bytes.data());
154 Span<DataType> orig_view = { orig_view_data, nb_value };
155 for (Int64 i = 0; i < nb_value; i += m_extent.v) {
156 // Uses a span to test array overflows but // could directly
157 // use 'orig_view_data' for better performance
158 for (Int32 z = 0, n = m_extent.v; z < n; ++z) {
159 orig_view[i + z] = source[z];
160 }
161 }
162 }
163 }
164 else {
165 ARCCORE_CHECK_POINTER(indexes.data());
166 for (Int32 i = 0; i < nb_index; ++i) {
167 Int32 index0 = indexes[i * 2];
168 Int32 index1 = indexes[(i * 2) + 1];
169 Span<std::byte> orig_view_bytes = multi_views[index0];
170 auto* orig_view_data = reinterpret_cast<DataType*>(orig_view_bytes.data());
171 // Uses a span to test array overflows but // could directly
172 // use 'orig_view_data' for better performance
173 Span<DataType> orig_view = { orig_view_data, orig_view_bytes.size() / (Int64)sizeof(DataType) };
174 Int64 zci = ((Int64)(index1)) * m_extent.v;
175 for (Int32 z = 0, n = m_extent.v; z < n; ++z)
176 orig_view[zci + z] = source[z];
177 }
178 }
179 }
180
181 void _copyTo(SmallSpan<const Int32> indexes, Span<const DataType> source,
182 Span<DataType> destination)
183 {
184 ARCCORE_CHECK_POINTER(indexes.data());
185 ARCCORE_CHECK_POINTER(source.data());
186 ARCCORE_CHECK_POINTER(destination.data());
187
188 Int32 nb_index = indexes.size();
189
190 for (Int32 i = 0; i < nb_index; ++i) {
191 Int64 z_index = (Int64)i * m_extent.v;
192 Int64 zci = (Int64)(indexes[i]) * m_extent.v;
193 for (Int32 z = 0, n = m_extent.v; z < n; ++z)
194 destination[zci + z] = source[z_index + z];
195 }
196 }
197
198 void _copyTo(SmallSpan<const Int32> indexes, SmallSpan<const Span<const std::byte>> multi_views,
199 Span<DataType> destination)
200 {
201 ARCCORE_CHECK_POINTER(indexes.data());
202 ARCCORE_CHECK_POINTER(destination.data());
203 ARCCORE_CHECK_POINTER(multi_views.data());
204
205 const Int32 value_size = indexes.size() / 2;
206 for (Int32 i = 0; i < value_size; ++i) {
207 Int32 index0 = indexes[i * 2];
208 Int32 index1 = indexes[(i * 2) + 1];
209 Span<const std::byte> orig_view_bytes = multi_views[index0];
210 auto* orig_view_data = reinterpret_cast<const DataType*>(orig_view_bytes.data());
211 // Uses a span to test array overflows but // could directly
212 // use 'orig_view_data' for better performance
213 Span<const DataType> orig_view = { orig_view_data, orig_view_bytes.size() / (Int64)sizeof(DataType) };
214 Int64 zci = ((Int64)(index1)) * m_extent.v;
215 Int64 z_index = (Int64)i * m_extent.v;
216 for (Int32 z = 0, n = m_extent.v; z < n; ++z)
217 destination[z_index + z] = orig_view[zci + z];
218 }
219 }
220};
221
222/*---------------------------------------------------------------------------*/
223/*---------------------------------------------------------------------------*/
224
225} // namespace Arcane::Impl
226
227/*---------------------------------------------------------------------------*/
228/*---------------------------------------------------------------------------*/
229
230#endif
#define ARCCORE_CHECK_POINTER(ptr)
Macro that returns the pointer ptr if it is not null or throws an exception if it is null.
Implementation of copies and filling on host.
void _fill(SmallSpan< const Int32 > indexes, Span< const DataType > source, Span< DataType > destination)
Fills the values at indices specified by indexes.
Arguments for copying specific indices between two memory regions.
Arguments for copying specific indices to/from multiple memory regions.
View of an array of elements of type T.
Definition Span.h:805
constexpr __host__ __device__ pointer data() const noexcept
Pointer to the start of the view.
Definition Span.h:539
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Definition Span.h:327
View of an array of elements of type T.
Definition Span.h:635
std::int64_t Int64
Signed integer type of 64 bits.
std::int32_t Int32
Signed integer type of 32 bits.