Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
SimdEMUL.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/* SimdEmulated.h (C) 2000-2016 */
9/* */
10/* Emulation of vectorization when no mechanism is available. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_SIMDEMULATED_H
13#define ARCANE_UTILS_SIMDEMULATED_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17/*
18 * This file should not be included directly.
19 * Use 'Simd.h' instead.
20 */
21
22/*---------------------------------------------------------------------------*/
23/*---------------------------------------------------------------------------*/
24
25namespace Arcane
26{
27
28/*---------------------------------------------------------------------------*/
29/*---------------------------------------------------------------------------*/
30
31/*!
32 * \ingroup ArcaneSimd
33 * \brief Integer vectorization using emulation.
34 */
35class EMULSimdX2Int32
36{
37 public:
38
39 static const int BLOCK_SIZE = 2;
40 enum
41 {
42 Length = 2,
43 Alignment = 4
44 };
45
46 public:
47
48 Int32 v0;
49 Int32 v1;
50 EMULSimdX2Int32() {}
51 explicit EMULSimdX2Int32(Int32 a)
52 : v0(a)
53 , v1(a)
54 {}
55
56 private:
57
58 EMULSimdX2Int32(Int32 a1, Int32 a0)
59 : v0(a0)
60 , v1(a1)
61 {}
62
63 public:
64
65 EMULSimdX2Int32(const Int32* base, const Int32* idx)
66 : v0(base[idx[0]])
67 , v1(base[idx[1]])
68 {}
69 explicit EMULSimdX2Int32(const Int32* base)
70 : v0(base[0])
71 , v1(base[1])
72 {}
73
74 Int32 operator[](Integer i) const { return (&v0)[i]; }
75 Int32& operator[](Integer i) { return (&v0)[i]; }
76
77 void set(ARCANE_RESTRICT Int32* base, const ARCANE_RESTRICT Int32* idx) const
78 {
79 base[idx[0]] = v0;
80 base[idx[1]] = v1;
81 }
82
83 void set(ARCANE_RESTRICT Int32* base) const
84 {
85 base[0] = v0;
86 base[1] = v1;
87 }
88
89 static EMULSimdX2Int32 fromScalar(Int32 a0, Int32 a1)
90 {
91 return EMULSimdX2Int32(a1, a0);
92 }
93
94 private:
95
96 void operator=(Int32 _v);
97};
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101
102/*!
103 * \ingroup ArcaneSimd
104 * \brief Integer vectorization using emulation.
105 */
106class EMULSimdX4Int32
107{
108 public:
109
110 static const int BLOCK_SIZE = 4;
111 enum
112 {
113 Length = 4,
114 Alignment = 4
115 };
116
117 public:
118
119 Int32 v0;
120 Int32 v1;
121 Int32 v2;
122 Int32 v3;
123 EMULSimdX4Int32() {}
124 explicit EMULSimdX4Int32(Int32 a)
125 : v0(a)
126 , v1(a)
127 , v2(a)
128 , v3(a)
129 {}
130
131 private:
132
133 EMULSimdX4Int32(Int32 a3, Int32 a2, Int32 a1, Int32 a0)
134 : v0(a0)
135 , v1(a1)
136 , v2(a2)
137 , v3(a3)
138 {}
139
140 public:
141
142 EMULSimdX4Int32(const Int32* base, const Int32* idx)
143 : v0(base[idx[0]])
144 , v1(base[idx[1]])
145 , v2(base[idx[2]])
146 , v3(base[idx[3]])
147 {}
148 explicit EMULSimdX4Int32(const Int32* base)
149 : v0(base[0])
150 , v1(base[1])
151 , v2(base[2])
152 , v3(base[3])
153 {}
154 explicit EMULSimdX4Int32(const EMULSimdX4Int32* base)
155 : v0(base->v0)
156 , v1(base->v1)
157 , v2(base->v2)
158 , v3(base->v3)
159 {}
160
161 Int32 operator[](Integer i) const { return (&v0)[i]; }
162 Int32& operator[](Integer i) { return (&v0)[i]; }
163
164 void set(ARCANE_RESTRICT Int32* base, const ARCANE_RESTRICT Int32* idx) const
165 {
166 base[idx[0]] = v0;
167 base[idx[1]] = v1;
168 base[idx[2]] = v2;
169 base[idx[3]] = v3;
170 }
171
172 void set(ARCANE_RESTRICT Int32* base) const
173 {
174 base[0] = v0;
175 base[1] = v1;
176 base[2] = v2;
177 base[3] = v3;
178 }
179
180 static EMULSimdX4Int32 fromScalar(Int32 a0, Int32 a1, Int32 a2, Int32 a3)
181 {
182 return EMULSimdX4Int32(a3, a2, a1, a0);
183 }
184
185 private:
186
187 void operator=(Int32 _v);
188};
189
190/*---------------------------------------------------------------------------*/
191/*---------------------------------------------------------------------------*/
192
193/*!
194 * \brief Real vectorization using emulation.
195 *
196 * This class is used when no vectorization mechanism is available. It is
197 * just an encapsulation of 2 reals. Other vector sizes could have been
198 * chosen (for example 4 or 8), but tests performed (in 2013) show that
199 * performance degrades beyond 2.
200 */
201class EMULSimdReal
202{
203 public:
204
205 static const int BLOCK_SIZE = 2;
206 enum : Int32
207 {
208 Length = 2
209 };
210 typedef EMULSimdX2Int32 Int32IndexType;
211 Real v0;
212 Real v1;
213 //NOTE: it is normal that this constructor does not perform initialization.
214 EMULSimdReal() {}
215 explicit EMULSimdReal(Real a)
216 : v0(a)
217 , v1(a)
218 {}
219
220 private:
221
222 EMULSimdReal(Real a0, Real a1)
223 : v0(a0)
224 , v1(a1)
225 {}
226
227 public:
228
229 EMULSimdReal(const Real* base)
230 : v0(base[0])
231 , v1(base[1])
232 {}
233 EMULSimdReal(const Real* base, const Int32* idx)
234 : v0(base[idx[0]])
235 , v1(base[idx[1]])
236 {}
237 EMULSimdReal(const Real* base, const Int32IndexType* idx)
238 : v0(base[idx->v0])
239 , v1(base[idx->v1])
240 {}
241 EMULSimdReal(const Real* base, const Int32IndexType& idx)
242 : v0(base[idx.v0])
243 , v1(base[idx.v1])
244 {}
245 const Real& operator[](Integer i) const { return ((Real*)this)[i]; }
246 Real& operator[](Integer i) { return ((Real*)this)[i]; }
247 void set(ARCANE_RESTRICT Real* base) const
248 {
249 base[0] = v0;
250 base[1] = v1;
251 }
252 void set(ARCANE_RESTRICT Real* base, const Int32* idx) const
253 {
254 base[idx[0]] = v0;
255 base[idx[1]] = v1;
256 }
257 void set(ARCANE_RESTRICT Real* base, const Int32IndexType* idx) const
258 {
259 base[idx->v0] = v0;
260 base[idx->v1] = v1;
261 }
262 void set(ARCANE_RESTRICT Real* base, const Int32IndexType& idx) const
263 {
264 base[idx.v0] = v0;
265 base[idx.v1] = v1;
266 }
267 static EMULSimdReal fromScalar(Real a0, Real a1)
268 {
269 return EMULSimdReal(a0, a1);
270 }
271
272 private:
273
274 void operator=(Real _v);
275};
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
281{
282 public:
283
284 static const char* name() { return "EMUL"; }
285 enum : Int32
286 {
287 Int32IndexSize = 2
288 };
289 typedef EMULSimdReal SimdReal;
290 typedef EMULSimdReal::Int32IndexType SimdInt32IndexType;
291};
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
296ARCANE_UTILS_EXPORT std::ostream&
297operator<<(std::ostream& o, const EMULSimdReal& s);
298
299// Unary operation operator-
300inline EMULSimdReal operator-(EMULSimdReal a)
301{
302 Real* za = (Real*)(&a);
303 return EMULSimdReal::fromScalar(-(za[0]), -(za[1]));
304}
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
309} // namespace Arcane
310
311/*---------------------------------------------------------------------------*/
312/*---------------------------------------------------------------------------*/
313
314#endif
Real vectorization using emulation.
Definition SimdEMUL.h:202
Integer vectorization using emulation.
Definition SimdEMUL.h:36
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
std::ostream & operator<<(std::ostream &ostr, eItemKind item_kind)
Output operator for a stream.
std::int32_t Int32
Signed integer type of 32 bits.