Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
TestArray.cc
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#include <gtest/gtest.h>
8
9#include "arccore/collections/Array.h"
10#include "arccore/collections/IMemoryAllocator.h"
11
12#include "arccore/base/FatalErrorException.h"
13#include "arccore/base/Iterator.h"
14
15#include "TestArrayCommon.h"
16
17using namespace Arccore;
18using namespace TestArccore;
19
20namespace
21{
22void _testArraySwap(bool use_own_swap)
23{
24 std::cout << "** TestArraySwap is_own=" << use_own_swap << "\n";
25
26 String c1_name = "TestC1";
28 c1.setDebugName(c1_name);
29 IntSubClass* x1 = c1.data();
30 std::cout << "** C1_this = " << &c1 << "\n";
31 std::cout << "** C1_BASE = " << x1 << "\n";
33 IntSubClass* x2 = c2.data();
34 std::cout << "** C2_this = " << &c2 << "\n";
35 std::cout << "** C2_BASE = " << x2 << "\n";
36
37 ASSERT_EQ(c1.debugName(), c1_name);
38 ASSERT_EQ(c2.debugName(), String{});
39
40 if (use_own_swap) {
41 swap(c1, c2);
42 }
43 else
44 std::swap(c1, c2);
45
46 ASSERT_EQ(c2.debugName(), c1_name);
47 ASSERT_EQ(c1.debugName(), String{});
48
49 IntSubClass* after_x1 = c1.data();
50 IntSubClass* after_x2 = c2.data();
51 std::cout << "** C1_BASE_AFTER = " << after_x1 << " size=" << c1.size() << "\n";
52 std::cout << "** C2_BASE_AFTER = " << after_x2 << " size=" << c2.size() << "\n";
53
54 ASSERT_TRUE(x1 == after_x2) << "Bad value after swap [1]";
55 ASSERT_TRUE(x2 == after_x1) << "Bad value after swap [2]";
56}
57} // namespace
58
59TEST(Array, Swap1)
60{
61 _testArraySwap(true);
62}
63
64TEST(Array, Swap2)
65{
66 _testArraySwap(false);
67}
68
69/*---------------------------------------------------------------------------*/
70/*---------------------------------------------------------------------------*/
71
72Integer IntPtrSubClass::count = 0;
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
77template <typename Container, typename SubClass>
79{
80 public:
81
82 void test()
83 {
84 {
85 Container c;
86 c.add(SubClass(1));
87 c.add(SubClass(2));
88 c.add(SubClass(3));
89 ARCCORE_UT_CHECK((c.size() == 3), "Bad size (3)");
90 ARCCORE_UT_CHECK((c[0] == 1), "Bad value [0]");
91 ARCCORE_UT_CHECK((c[1] == 2), "Bad value [1]");
92 ARCCORE_UT_CHECK((c[2] == 3), "Bad value [2]");
93 c.resize(0);
94 ARCCORE_UT_CHECK((c.size() == 0), "Bad size (0)");
95 c.resize(5);
96 ARCCORE_UT_CHECK((c.size() == 5), "Bad size");
97 c.add(SubClass(6));
98 ARCCORE_UT_CHECK((c.size() == 6), "Bad size");
99 ARCCORE_UT_CHECK((c[5] == 6), "Bad value [5]");
100 c.shrink();
101 ASSERT_EQ(c.size(), c.capacity()) << "Bad capacity (test 1)";
102 c.resize(12);
103 c.shrink();
104 ASSERT_EQ(c.size(), c.capacity()) << "Bad capacity (test 2)";
105 }
106 {
107 Container c;
108 c.shrink();
109 ASSERT_EQ(c.capacity(), 0) << "Bad capacity (test 3)";
110 }
111 {
112 Container c;
113 Integer nb = 20;
114 for (Integer i = 0; i < nb; ++i)
115 c.add(SubClass(i));
116 c.reserve(nb * 2);
117 Int64 current_capacity = c.capacity();
118 ASSERT_EQ(current_capacity, (nb * 2)) << "Bad capacity (test 4)";
119 c.shrink(c.capacity() + 5);
120 ASSERT_EQ(c.capacity(), current_capacity) << "Bad capacity (test 5)";
121 c.shrink(32);
122 ASSERT_EQ(c.capacity(), 32) << "Bad capacity (test 6)";
123 c.shrink();
124 ASSERT_EQ(c.capacity(), c.size()) << "Bad capacity (test 7)";
125 }
126 {
128 Integer nb = 1000000;
129 uc.resize(1000);
130 for (Container& c : uc) {
131 c.reserve(nb);
132 c.shrink_to_fit();
133 }
134 }
135 {
136 Container c;
137 for (Integer i = 0; i < 50; ++i)
138 c.add(SubClass(i + 2));
139 {
140 Container c2 = c;
141 for (Integer i = 50; i < 100; ++i) {
142 c2.add(SubClass(i + 2));
143 }
144 Container c4 = c2;
145 Container c3;
146 c3.add(5);
147 c3.add(6);
148 c3.add(7);
149 c3 = c2;
150 for (Integer i = 100; i < 150; ++i) {
151 c4.add(SubClass(i + 2));
152 }
153 }
154 ARCCORE_UT_CHECK((c.size() == 150), "Bad size (150)");
155 c.reserve(300);
156 ARCCORE_UT_CHECK((c.capacity() == 300), "Bad capacity (300)");
157 for (Integer i = 0; i < 50; ++i) {
158 c.remove(i);
159 }
160 ARCCORE_UT_CHECK((c.size() == 100), "Bad size (100)");
161 for (Integer i = 0; i < 50; ++i) {
162 //cout << "** VAL: " << i << " c=" << c[i] << " expected=" << ((i*2)+3) << '\n';
163 ARCCORE_UT_CHECK((c[i] == ((i * 2) + 3)), "Bad value");
164 }
165 for (Integer i = 50; i < 100; ++i) {
166 //cout << "** VAL: " << i << " c=" << c[i] << " expected=" << (i+52) << '\n';
167 ARCCORE_UT_CHECK((c[i] == (i + 52)), "Bad value");
168 }
169 }
170 }
171};
172
173namespace
174{
175void _testArrayNewInternal()
176{
177 using namespace Arccore;
178 std::cout << "** TEST VECTOR NEW\n";
179
180 std::cout << "** wanted_size = " << AlignedMemoryAllocator3::simdAlignment() << "\n";
181 //if (impl_size!=wanted_size)
182 //ARCCORE_FATAL("Bad sizeof(ArrayImplBase) v={0} expected={1}",impl_size,wanted_size);
183 {
185 rvt.test();
186 }
187 std::cout << "** TEST VECTOR NEW 2\n";
188 {
190 rvt.test();
191 std::cout << "** COUNT = " << IntPtrSubClass::count << "\n";
192 }
193 std::cout << "** TEST VECTOR NEW 3\n";
194 {
196 rvt.test();
197 std::cout << "** COUNT = " << IntPtrSubClass::count << "\n";
198 }
199 {
201 c.add(5);
202 c.add(7);
204 c2.add(3);
205 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
206 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
207 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
208 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
209 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
210 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
211 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
212 }
213 {
215 c.add(5);
216 c.add(7);
218 c2.add(3);
219 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
220 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
221 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
222 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
223 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
224 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
225 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
226 }
227 {
228 UniqueArray<IntSubClass> c{ 5, 7 };
230 c2.add(3);
231 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
232 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
233 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
234 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
235 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
236 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
237 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
238 }
239 {
240 UniqueArray<IntSubClass> c{ 5, 7 };
241 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
242 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
243 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
244 }
245 {
246 SharedArray<IntSubClass> c{ 5, 7 };
247 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
248 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
249 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
250 }
251 {
252 PrintableMemoryAllocator allocator;
253 UniqueArray<IntSubClass> c(&allocator);
254 UniqueArray<IntSubClass> cx(&allocator, 5);
255 ARCCORE_UT_CHECK((cx.size() == 5), "Bad value [5]");
256 c.add(5);
257 c.add(7);
259 c2.add(3);
260 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
261 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
262 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
263 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
264 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
265 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
266 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
267 for (Integer i = 0; i < 50; ++i)
268 c.add(i + 3);
269 c.resize(24);
270 c.reserve(70);
271 }
272 {
274 c2.add(3);
275 c2.add(5);
277 ASSERT_EQ(c22.size(), 33);
278 c22 = c2;
279 {
281 c.add(5);
282 c.add(7);
283 c2 = c;
286 c2.resize(125);
287 ASSERT_EQ(c2.size(), c3.size());
288 ASSERT_EQ(c2.size(), c4.size());
289 c3.resize(459);
290 ASSERT_EQ(c2.size(), c3.size());
291 ASSERT_EQ(c2.size(), c4.size());
292 c4.resize(932);
293 c.resize(32);
294 }
295 c2.add(3);
296 ARCCORE_UT_CHECK((c2.size() == 33), "Bad value [3]");
297 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
298 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
299 ARCCORE_UT_CHECK((c2[32] == 3), "Bad value [7]");
300 c2.resize(1293);
301 ASSERT_EQ(c2.size(), 1293);
302 ASSERT_EQ(c22.size(), 2);
303
304 {
305 SharedArray<IntSubClass> values1 = { -7, 3, 4 };
306 ASSERT_EQ(values1.size(), 3);
307 ASSERT_EQ(values1[0], -7);
308 ASSERT_EQ(values1[1], 3);
309 ASSERT_EQ(values1[2], 4);
310 values1 = { 2, -1, 9, 13 };
311 ASSERT_EQ(values1.size(), 4);
312 ASSERT_EQ(values1[0], 2);
313 ASSERT_EQ(values1[1], -1);
314 ASSERT_EQ(values1[2], 9);
315 ASSERT_EQ(values1[3], 13);
316 SharedArray<IntSubClass> values2 = values1;
317 ASSERT_EQ(values2, values1);
318
319 values1 = {};
320 ASSERT_EQ(values1.size(), 0);
321 ASSERT_EQ(values2.size(), 0);
322 }
323 }
324 {
325 UniqueArray<Int32> values1 = { 2, 5 };
326 UniqueArray<Int32> values2 = { 4, 9, 7 };
327 // Copy the values of values2 to the end of values1.
328 std::copy(std::begin(values2), std::end(values2), std::back_inserter(values1));
329 std::cout << "** VALUES1 = " << values1 << "\n";
330 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
331 ARCCORE_UT_CHECK((values1[0] == 2), "BI: Bad value [0]");
332 ARCCORE_UT_CHECK((values1[1] == 5), "BI: Bad value [1]");
333 ARCCORE_UT_CHECK((values1[2] == 4), "BI: Bad value [2]");
334 ARCCORE_UT_CHECK((values1[3] == 9), "BI: Bad value [3]");
335 ARCCORE_UT_CHECK((values1[4] == 7), "BI: Bad value [4]");
336
338 vx.add(IntPtrSubClass(5));
339 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
341 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
342
343 values1 = { -7, 3 };
344 ASSERT_EQ(values1.size(), 2);
345 ASSERT_EQ(values1[0], -7);
346 ASSERT_EQ(values1[1], 3);
347
348 values1 = {};
349 ASSERT_EQ(values1.size(), 0);
350 }
351 {
352 UniqueArray<Int32> values1;
353 UniqueArray<Int32> values2 = { 4, 9, 7, 6, 3 };
354 // Copy the values of values2 to the end of values1.
355 values1.copy(values2);
356 std::cout << "** VALUES1 = " << values1 << "\n";
357 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
358 ARCCORE_UT_CHECK((values1[0] == 4), "BI2: Bad value [0]");
359 ARCCORE_UT_CHECK((values1[1] == 9), "BI2: Bad value [1]");
360 ARCCORE_UT_CHECK((values1[2] == 7), "BI2: Bad value [2]");
361 ARCCORE_UT_CHECK((values1[3] == 6), "BI2: Bad value [3]");
362 ARCCORE_UT_CHECK((values1[4] == 3), "BI2: Bad value [4]");
363
365 vx.add(IntPtrSubClass(5));
366 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
368 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
369 }
370 {
372 vx.add(IntPtrSubClass(5));
375 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
378 std::cout << "V=" << cicvx->m_v << '\n';
379 }
380 {
382 vx.add(IntPtrSubClass(5));
383 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
384 UniqueArray<IntPtrSubClass>::iterator iend = std::end(vx);
386 std::cout << "V=" << i->m_v << " " << ci->m_v << " " << (iend - i) << '\n';
388 UniqueArray<IntPtrSubClass>::const_iterator cicvx = std::begin(cvx);
389 std::cout << "V=" << cicvx->m_v << '\n';
390 std::copy(std::begin(vx), std::end(vx), std::begin(vx));
391 }
392 {
393 UniqueArray<Int32> values = { 4, 9, 7 };
394 for (typename ArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
395 std::cout << *i << '\n';
396 }
397 for (typename ConstArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
398 std::cout << *i << '\n';
399 }
400 for (auto i : values.range()) {
401 std::cout << i << '\n';
402 }
403 for (auto i : values.constView().range()) {
404 std::cout << i << '\n';
405 }
406
407 {
408 auto r1 = std::make_reverse_iterator(values.end());
409 auto r2 = std::make_reverse_iterator(values.begin());
410 for (; r1 != r2; ++r1) {
411 std::cout << "RVALUE = " << *r1 << '\n';
412 }
413 }
414 {
415 auto r1 = values.rbegin();
416 ASSERT_EQ((*r1), 7);
417 ++r1;
418 ASSERT_EQ((*r1), 9);
419 ++r1;
420 ASSERT_EQ((*r1), 4);
421 ++r1;
422 ASSERT_TRUE((r1 == values.rend()));
423 }
424 {
427 c2.add(IntSubClassNoPod{ 3 });
428 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
429 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
430 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
431 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
432 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
433 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
434 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
435 c = c2.span();
436 SmallSpan<const IntSubClassNoPod> c2_small_span = c2;
437 ASSERT_EQ(c.constSpan(), c2.constSpan());
438 ASSERT_EQ(c.constSmallSpan(), c2_small_span);
439 ASSERT_EQ(c.smallSpan(), c2.smallSpan());
440 }
441 }
442}
443} // namespace
444
445/*---------------------------------------------------------------------------*/
446/*---------------------------------------------------------------------------*/
447
448TEST(Array, Misc)
449{
450 try {
451 _testArrayNewInternal();
452 }
453 catch (const Exception& ex) {
454 std::cerr << "Exception ex=" << ex << "\n";
455 throw;
456 }
457}
458
459/*---------------------------------------------------------------------------*/
460/*---------------------------------------------------------------------------*/
461
462namespace
463{
464void _Add(Array<Real>& v, Integer new_size)
465{
466 v.resize(new_size);
467}
468} // namespace
469
470/*---------------------------------------------------------------------------*/
471/*---------------------------------------------------------------------------*/
472
473TEST(Array, Misc2)
474{
475 using namespace Arccore;
476 {
478 v.resize(3);
479 v[0] = 1.2;
480 v.at(1) = -1.3;
481 v[2] = 7.6;
482 ASSERT_EQ(v[0], 1.2);
483 ASSERT_EQ(v[1], -1.3);
484 ASSERT_EQ(v.at(2), 7.6);
485
486 v.add(4.3);
487 for (Real x : v) {
488 std::cout << " Value: " << x << '\n';
489 }
490 v.printInfos(std::cout);
491 }
492 {
494 v.add(4.3);
495 v.add(5.3);
496 v.add(4.6);
497 v.printInfos(std::cout);
498 v.add(14.3);
499 v.add(25.3);
500 v.add(34.6);
501 v.printInfos(std::cout);
502 v.resize(4);
503 v.printInfos(std::cout);
504 v.add(12.2);
505 v.add(2.4);
506 v.add(3.4);
507 v.add(3.6);
508 v.printInfos(std::cout);
509 for (Integer i = 0, is = v.size(); i < is; ++i) {
510 std::cout << " Value: " << v[i] << '\n';
511 }
512 }
513 {
515 v.reserve(5);
516 for (int i = 0; i < 10; ++i)
517 v.add((Real)i);
518 for (Integer i = 0, is = v.size(); i < is; ++i) {
519 std::cout << " Value: " << v[i] << '\n';
520 }
521 }
522 {
524 v.reserve(175);
525 for (int i = 0; i < 27500; ++i) {
526 Real z = (Real)i;
527 v.add(z * z);
528 }
529 for (int i = 0; i < 5000; ++i) {
530 v.remove(i * 2);
531 }
532 v.reserve(150);
533 for (int i = 0; i < 27500; ++i) {
534 Real z = (Real)i;
535 v.add(z * z);
536 }
537 std::cout << " ValueSize= " << v.size() << " values=" << v << '\n';
538 }
539 for (Integer i = 0; i < 100; ++i) {
541 _Add(v, 500000);
542 _Add(v, 1000000);
543 _Add(v, 0);
544 _Add(v, 100000);
545 _Add(v, 0);
546 _Add(v, 0);
547 _Add(v, 230000);
548 std::cout << " Size: " << v.size() << '\n';
549 ASSERT_EQ(v.size(), 230000);
550 }
551}
552
553/*---------------------------------------------------------------------------*/
554/*---------------------------------------------------------------------------*/
555
556TEST(Array, SubViews)
557{
558 using namespace Arccore;
559
560 {
561 // Test Array::subView() and Array::subConstView()
563 v.resize(23);
564 for (Int32 i = 0, n = v.size(); i < n; ++i)
565 v[i] = (i + 1);
566
567 auto sub_view1 = v.subView(50, 5);
568 ASSERT_EQ(sub_view1.data(), nullptr);
569 ASSERT_EQ(sub_view1.size(), 0);
570
571 auto sub_view2 = v.subView(2, 8);
572 ASSERT_EQ(sub_view2.size(), 8);
573 for (Int32 i = 0, n = sub_view2.size(); i < n; ++i)
574 ASSERT_EQ(sub_view2[i], v[2 + i]);
575
576 auto sub_view3 = v.subView(20, 8);
577 ASSERT_EQ(sub_view3.size(), 3);
578 for (Int32 i = 0, n = sub_view3.size(); i < n; ++i)
579 ASSERT_EQ(sub_view3[i], v[20 + i]);
580
581 auto sub_const_view1 = v.subConstView(50, 5);
582 ASSERT_EQ(sub_const_view1.data(), nullptr);
583 ASSERT_EQ(sub_const_view1.size(), 0);
584
585 auto sub_const_view2 = v.subConstView(2, 8);
586 ASSERT_EQ(sub_const_view2.size(), 8);
587 for (Int32 i = 0, n = sub_const_view2.size(); i < n; ++i)
588 ASSERT_EQ(sub_const_view2[i], v[2 + i]);
589
590 auto sub_const_view3 = v.subConstView(20, 8);
591 ASSERT_EQ(sub_const_view3.size(), 3);
592 for (Int32 i = 0, n = sub_const_view3.size(); i < n; ++i)
593 ASSERT_EQ(sub_const_view3[i], v[20 + i]);
594 }
595}
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
600class NoCopyData
601{
602 public:
603
604 NoCopyData(const NoCopyData& x) = delete;
605};
606
607template <typename DataType>
609: public Arccore::Array<DataType>
610{
611 public:
612
613 using BaseClass = Arccore::Array<DataType>;
614};
615
616/*---------------------------------------------------------------------------*/
617/*---------------------------------------------------------------------------*/
618
619TEST(Array, Misc3)
620{
621 using namespace Arccore;
622
623 {
625 const Int32 ref_value1 = 12;
626 const Int32 ref_value2 = 7;
627
628 c.resize(9, IntSubClassNoPod(ref_value1));
629 std::cout << "C1=" << c << "\n";
630 for (IntSubClassNoPod x : c)
631 ASSERT_EQ(x, ref_value1);
632
633 c.resize(21, IntSubClassNoPod(ref_value2));
634 ASSERT_EQ(c.size(), 21);
635 std::cout << "C2=" << c << "\n";
636
637 // Resize without initializing. The values for elements
638 // from 9 to 18 must be \a ref_value2
639 c.resizeNoInit(18);
640 std::cout << "C4=" << c << "\n";
641 for (Int32 i = 9, s = c.size(); i < s; ++i)
642 ASSERT_EQ(c[i], ref_value2);
643 for (Int32 i = 9, s = c.size(); i < s; ++i)
644 new (c.data() + i) IntSubClassNoPod(i + 2);
645 for (Int32 i = 9, s = c.size(); i < s; ++i)
646 ASSERT_EQ(c[i], (i + 2));
647 }
648 {
650 c2.resizeNoInit(25);
651 }
652}
653
654/*---------------------------------------------------------------------------*/
655/*---------------------------------------------------------------------------*/
656
657template <typename ArrayType>
659{
660 public:
661
662 static void doTestBase()
663 {
664 using namespace Arccore;
665
667 PrintableMemoryAllocator printable_allocator2;
668 IMemoryAllocator* allocator2 = &printable_allocator2;
669
670 {
671 std::cout << "Array a\n";
672 ArrayType a(allocator1);
673 ASSERT_EQ(a.allocator(), allocator1);
674 a.add(27);
675 a.add(38);
676 a.add(13);
677 a.add(-5);
678
679 std::cout << "Array b\n";
680 ArrayType b(allocator2);
681 ASSERT_EQ(b.capacity(), 0);
682 ASSERT_EQ(b.size(), 0);
683 ASSERT_EQ(b.allocator(), allocator2);
684
685 b = a;
686 ASSERT_EQ(b.size(), a.size());
687 ASSERT_EQ(b.allocator(), a.allocator());
688
689 std::cout << "Array c\n";
690 ArrayType c(a.clone());
691 ASSERT_EQ(c.allocator(), a.allocator());
692 ASSERT_EQ(c.size(), a.size());
693 ASSERT_EQ(c.constSpan(), a.constSpan());
694
695 std::cout << "Array d\n";
696 ArrayType d(allocator2, a);
697 ASSERT_EQ(d.allocator(), allocator2);
698 ASSERT_EQ(d.size(), a.size());
699 ASSERT_EQ(d.constSpan(), a.constSpan());
700
701 std::cout << "Array e\n";
702 ArrayType e(allocator2, 25);
703 ASSERT_EQ(e.allocator(), allocator2);
704 ASSERT_EQ(e.size(), 25);
705
706 ArrayType f(allocator2);
707 f = e;
708 ASSERT_EQ(f.allocator(), e.allocator());
709 ASSERT_EQ(f.size(), e.size());
710
711 f = f;
712 ASSERT_EQ(f.allocator(), e.allocator());
713 ASSERT_EQ(f.size(), e.size());
714 }
715 }
716};
717
718TEST(UniqueArray, AllocatorBase)
719{
721}
722
723TEST(SharedArray, AllocatorBase)
724{
726}
727
728/*---------------------------------------------------------------------------*/
729/*---------------------------------------------------------------------------*/
730
732{
733 using namespace Arccore;
734 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
735 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
736 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
737 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
738
739 PrintableMemoryAllocator printable_allocator;
740 PrintableMemoryAllocator printable_allocator2;
743 {
744 std::cout << "Array a1\n";
745 UniqueArray<Int32> a1(allocator2);
746 ASSERT_EQ(a1.allocator(), allocator2);
747 ASSERT_EQ(a1.size(), 0);
748 ASSERT_EQ(a1.capacity(), 0);
749 ASSERT_EQ(a1.data(), nullptr);
750
751 std::cout << "Array a2\n";
752 UniqueArray<Int32> a2(a1);
753 ASSERT_EQ(a1.allocator(), a2.allocator());
754 ASSERT_EQ(a2.capacity(), 0);
755 ASSERT_EQ(a2.data(), nullptr);
756 a1.reserve(3);
757 a1.add(5);
758 a1.add(7);
759 a1.add(12);
760 a1.add(3);
761 a1.add(1);
762 ASSERT_EQ(a1.size(), 5);
763
764 std::cout << "Array a3\n";
765 UniqueArray<Int32> a3(allocator1);
766 a3.add(4);
767 a3.add(6);
768 a3.add(2);
769 ASSERT_EQ(a3.size(), 3);
770 a3 = a1;
771 ASSERT_EQ(a3.allocator(), a1.allocator());
772 ASSERT_EQ(a3.size(), a1.size());
773 ASSERT_EQ(a3.constSpan(), a1.constSpan());
774
775 std::cout << "Array a4\n";
776 UniqueArray<Int32> a4(allocator1);
777 a4.add(4);
778 a4.add(6);
779 a4.add(2);
780 ASSERT_EQ(a4.size(), 3);
781 a4 = a1.span();
782 ASSERT_EQ(a4.allocator(), allocator1);
783
784 a4 = UniqueArray<Int32>(&printable_allocator2);
785
786 UniqueArray<Int32> array[2];
787 IMemoryAllocator* allocator3 = allocator1;
788 for (Integer i = 0; i < 2; ++i) {
789 array[i] = UniqueArray<Int32>(allocator3);
790 }
791 ASSERT_EQ(array[0].allocator(), allocator3);
792 ASSERT_EQ(array[1].allocator(), allocator3);
793 }
794}
795
796/*---------------------------------------------------------------------------*/
797/*---------------------------------------------------------------------------*/
798
800{
801 using namespace Arccore;
802 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
803 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
804 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
805 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
806
807 PrintableMemoryAllocator printable_allocator;
808 PrintableMemoryAllocator printable_allocator2;
811 {
812 std::cout << "Array a1\n";
813 SharedArray<Int32> a1(allocator2);
814 ASSERT_EQ(a1.allocator(), allocator2);
815 ASSERT_EQ(a1.size(), 0);
816 ASSERT_EQ(a1.capacity(), 0);
817 ASSERT_EQ(a1.data(), nullptr);
818
819 std::cout << "Array a2\n";
820 SharedArray<Int32> a2(a1);
821 ASSERT_EQ(a1.allocator(), a2.allocator());
822 ASSERT_EQ(a2.capacity(), 0);
823 ASSERT_EQ(a2.data(), nullptr);
824 a1.reserve(3);
825 a1.add(5);
826 a1.add(7);
827 a1.add(12);
828 a1.add(3);
829 a1.add(1);
830 ASSERT_EQ(a1.size(), 5);
831
832 std::cout << "Array a3\n";
834 a3.add(4);
835 a3.add(6);
836 a3.add(2);
837 ASSERT_EQ(a3.size(), 3);
838 a3 = a1;
839 ASSERT_EQ(a3.allocator(), a1.allocator());
840 ASSERT_EQ(a3.size(), a1.size());
841 ASSERT_EQ(a3.constSpan(), a1.constSpan());
842
843 std::cout << "Array a4\n";
844 SharedArray<Int32> a4(allocator1, 2);
845 ASSERT_EQ(a4.size(), 2);
846 a4.add(4);
847 a4.add(6);
848 a4.add(2);
849 ASSERT_EQ(a4.size(), 5);
850 ASSERT_EQ(a4[2], 4);
851 ASSERT_EQ(a4[3], 6);
852 ASSERT_EQ(a4[4], 2);
853
854 a4 = a1.span();
855 ASSERT_EQ(a4.allocator(), allocator1);
856
857 a4 = SharedArray<Int32>(&printable_allocator2);
858
859 SharedArray<Int32> array[2];
860 IMemoryAllocator* allocator3 = allocator1;
861 for (Integer i = 0; i < 2; ++i) {
862 array[i] = SharedArray<Int32>(allocator3);
863 }
864 ASSERT_EQ(array[0].allocator(), allocator3);
865 ASSERT_EQ(array[1].allocator(), allocator3);
866 }
867}
868
877: public IMemoryAllocator3
878{
879 public:
880
881 bool hasRealloc(MemoryAllocationArgs args) const override
882 {
883 _checkValid(args);
884 return m_default_allocator.hasRealloc(args);
885 }
886 AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
887 {
888 _checkValid(args);
889 return m_default_allocator.allocate(args, new_size);
890 }
891 AllocatedMemoryInfo reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size) override
892 {
893 _checkValid(args);
894 return m_default_allocator.reallocate(args, current_ptr, new_size);
895 }
896 void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo ptr) override
897 {
898 _checkValid(args);
899 m_default_allocator.deallocate(args, ptr);
900 }
901 Int64 adjustedCapacity(MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const override
902 {
903 _checkValid(args);
904 return m_default_allocator.adjustedCapacity(args, wanted_capacity, element_size);
905 }
906 size_t guaranteedAlignment(MemoryAllocationArgs args) const override
907 {
908 _checkValid(args);
909 return m_default_allocator.guaranteedAlignment(args);
910 }
911
912 void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr) override
913 {
914 // This method is only called once so we test the expected values directly
915 ASSERT_EQ(old_args.memoryLocationHint(), eMemoryLocationHint::None);
916 ASSERT_EQ(new_args.memoryLocationHint(), eMemoryLocationHint::MainlyHost);
917 ASSERT_EQ(ptr.size(), 8);
918 m_default_allocator.notifyMemoryArgsChanged(old_args, new_args, ptr);
919 }
920
921 private:
922
923 DefaultMemoryAllocator3 m_default_allocator;
924
925 private:
926
927 static void _checkValid(MemoryAllocationArgs args)
928 {
929 bool v1 = args.memoryLocationHint() == eMemoryLocationHint::None;
930 bool v2 = args.memoryLocationHint() == eMemoryLocationHint::MainlyHost;
931 bool v3 = args.memoryLocationHint() == eMemoryLocationHint::HostAndDeviceMostlyRead;
932 bool is_valid = v1 || v2 || v3;
933 ASSERT_TRUE(is_valid);
934 }
935};
936
937#define ASSERT_SAME_ARRAY_INFOS(a, b) \
938 ASSERT_EQ(a.allocationOptions(), b.allocationOptions()); \
939 ASSERT_EQ(a.size(), b.size()); \
940 ASSERT_EQ(a.capacity(), b.capacity())
941
942TEST(Array, AllocatorV2)
943{
944 using namespace Arccore;
945 TesterMemoryAllocatorV3 testerv2_allocator;
946 TesterMemoryAllocatorV3 testerv2_allocator2;
947 MemoryAllocationOptions allocate_options1(&testerv2_allocator, eMemoryLocationHint::HostAndDeviceMostlyRead);
948 MemoryAllocationOptions allocate_options2(&testerv2_allocator, eMemoryLocationHint::None, 0);
949 {
950 MemoryAllocationOptions opt3(&testerv2_allocator);
951 opt3.setMemoryLocationHint(eMemoryLocationHint::HostAndDeviceMostlyRead);
952 ASSERT_EQ(opt3, allocate_options1);
953 }
954 {
955 std::cout << "Array a1\n";
956 UniqueArray<Int32> a1(allocate_options2);
957 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
958 ASSERT_EQ(a1.size(), 0);
959 ASSERT_EQ(a1.capacity(), 0);
960 ASSERT_EQ(a1.data(), nullptr);
961
962 std::cout << "Array a2\n";
963 UniqueArray<Int32> a2(a1);
964 ASSERT_SAME_ARRAY_INFOS(a2, a1);
965 ASSERT_EQ(a2.data(), nullptr);
966 a1.reserve(3);
967 a1.add(5);
968 a1.add(7);
969 a1.add(12);
970 a1.add(3);
971 a1.add(1);
972 ASSERT_EQ(a1.size(), 5);
973 a2.add(9);
974 a2.add(17);
975 // To test notifyMemoryArgsChanged()
976 a2.setMemoryLocationHint(eMemoryLocationHint::MainlyHost);
977
978 std::cout << "Array a3\n";
979 UniqueArray<Int32> a3(allocate_options1);
980 a3.add(4);
981 a3.add(6);
982 a3.add(2);
983 ASSERT_EQ(a3.size(), 3);
984 a3 = a1;
985 ASSERT_EQ(a3.allocator(), a1.allocator());
986 ASSERT_EQ(a3.size(), a1.size());
987 ASSERT_EQ(a3.constSpan(), a1.constSpan());
988
989 std::cout << "Array a4\n";
990 UniqueArray<Int32> a4(allocate_options1);
991 a4.add(4);
992 a4.add(6);
993 a4.add(2);
994 ASSERT_EQ(a4.size(), 3);
995 a4 = a1.span();
996 ASSERT_EQ(a4.allocationOptions(), allocate_options1);
997
998 a4 = UniqueArray<Int32>(&testerv2_allocator2);
999
1000 UniqueArray<Int32> array[2];
1001 MemoryAllocationOptions allocator3 = allocate_options1;
1002 for (Integer i = 0; i < 2; ++i) {
1003 array[i] = UniqueArray<Int32>(allocator3);
1004 }
1005 ASSERT_EQ(array[0].allocationOptions(), allocator3);
1006 ASSERT_EQ(array[1].allocationOptions(), allocator3);
1007 }
1008}
1009
1010/*---------------------------------------------------------------------------*/
1011/*---------------------------------------------------------------------------*/
1012
1013TEST(Array, DebugInfo)
1014{
1015 using namespace Arccore;
1016 DefaultMemoryAllocator3 m_default_allocator;
1017 MemoryAllocationOptions allocate_options2(&m_default_allocator, eMemoryLocationHint::None, 0);
1018
1019 String a1_name("Array1");
1020 String sa1_name("SharedArray1");
1022 {
1023 std::cout << "Array a1\n";
1024 UniqueArray<Int32> a1(allocate_options2);
1025 a1.setDebugName(a1_name);
1026 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
1027 ASSERT_EQ(a1.size(), 0);
1028 ASSERT_EQ(a1.capacity(), 0);
1029 ASSERT_EQ(a1.data(), nullptr);
1030 ASSERT_EQ(a1.debugName(), a1_name);
1031
1032 std::cout << "SharedArray sa1\n";
1033 SharedArray<Int32> sa1(allocate_options2);
1034 sa1.setDebugName(sa1_name);
1035 ASSERT_EQ(sa1.allocationOptions(), allocate_options2);
1036 ASSERT_EQ(sa1.size(), 0);
1037 ASSERT_EQ(sa1.capacity(), 0);
1038 ASSERT_EQ(sa1.data(), nullptr);
1039 ASSERT_EQ(sa1.debugName(), sa1_name);
1040
1041 ASSERT_EQ(a1.debugName(), a1_name);
1042
1043 std::cout << "Array a2\n";
1044 UniqueArray<Int32> a2(a1);
1045 ASSERT_SAME_ARRAY_INFOS(a2, a1);
1046 ASSERT_EQ(a2.data(), nullptr);
1047 ASSERT_EQ(a2.debugName(), a1_name);
1048 a1.reserve(3);
1049 a1.add(5);
1050 a1.add(7);
1051 a1.add(12);
1052 a1.add(3);
1053 a1.add(1);
1054 ASSERT_EQ(a1.size(), 5);
1055 a2.add(9);
1056 a2.add(17);
1057 ASSERT_EQ(a2.debugName(), a1_name);
1058 ASSERT_EQ(a2.size(), 2);
1059
1060 a3 = a2;
1061 }
1062 ASSERT_EQ(a3.debugName(), a1_name);
1063 ASSERT_EQ(a3.size(), 2);
1064}
1065
1066/*---------------------------------------------------------------------------*/
1067/*---------------------------------------------------------------------------*/
1068
1069TEST(Collections, Memory)
1070{
1071 using namespace Arccore;
1072 std::cout << eHostDeviceMemoryLocation::Unknown << " "
1077
1078 std::cout << eMemoryResource::Unknown << " "
1079 << eMemoryResource::Host << " "
1081 << eMemoryResource::Device << " "
1083
1088}
1089
1090/*---------------------------------------------------------------------------*/
1091/*---------------------------------------------------------------------------*/
1092
1093namespace Arcane
1094{
1095// Explicitly instantiates array classes to ensure
1096// that all methods work
1097template class UniqueArray<IntSubClass>;
1098template class SharedArray<IntSubClass>;
1099template class Array<IntSubClass>;
1100template class AbstractArray<IntSubClass>;
1101} // namespace Arcane
#define ASSERT_TRUE(condition)
Checks that condition is true.
Definition Assertion.h:128
String debugName() const
Debug name (null if no name specified).
Abstract base class for a vector.
void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location)
Sets the physical location of the memory region.
Integer size() const
Number of elements in the vector.
ArrayIterator< pointer > iterator
Type of the iterator over an array element.
eHostDeviceMemoryLocation hostDeviceMemoryLocation() const
Sets the physical location of the memory region.
ArrayIterator< const_pointer > const_iterator
Type of the constant iterator over an array element.
static constexpr Integer simdAlignment()
Alignment for structures using vectorization.
static AlignedMemoryAllocator * Simd()
Allocator guaranteeing alignment to use vectorization on the target platform.
Information about an allocated memory region.
Int64 size() const
Size in bytes of the used memory region. (-1) if unknown.
Array Metadata.
ConstIterT< ArrayView< T > > const_iter
Type of a constant iterator over the entire array.
Base class for 1D data vectors.
SmallSpan< const T > smallSpan() const
Immutable view of this array.
reverse_iterator rbegin()
Reverse iterator over the first element of the array.
T & at(Int64 i)
Element at index i. Always checks for overflows.
void resizeNoInit(Int64 s)
Resizes without initializing new values.
Span< const T > span() const
Immutable view of this array.
void resize(Int64 s)
Changes the number of elements in the array to s.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sub-view starting from element abegin and containing asize elements.
void copy(Span< const T > rhs)
Copies the values from rhs into the instance.
SmallSpan< const T > constSmallSpan() const
Immutable view of this array.
iterator begin()
Iterator over the first element of the array.
void add(ConstReferenceType val)
Adds element val to the end of the array.
ConstArrayView< T > constView() const
Constant view of this array.
ArrayRange< pointer > range()
Iteration range from the first to the last element.
void remove(Int64 index)
Removes the entity at index index.
Span< const T > constSpan() const
Constant view of this array.
void reserve(Int64 new_capacity)
Reserves memory for new_capacity elements.
reverse_iterator rend()
Reverse iterator over the first element after the end of the array.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sub-view starting from element abegin and containing asize elements.
iterator end()
Iterator over the first element after the end of the array.
ArrayView< T > view() const
Mutable view of this array.
ConstIterT< ConstArrayView< T > > const_iter
Type of a constant iterator over the entire array.
Class containing information to specialize allocations.
Memory allocator via malloc/realloc/free with listing output.
1D vector of data with reference semantics.
SharedArray< T > clone() const
Clones the array.
View of an array of elements of type T.
Definition Span.h:805
1D data vector with value semantics (STL style).
Allocator for testing arguments.
Definition TestArray.cc:878
Concept for allocating, resizing and freeing memory block.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
void swap(UniqueArray2< T > &v1, UniqueArray2< T > &v2)
Swaps the values of v1 and v2.
Int32 Integer
Type representing an integer.
@ MainlyHost
Indicates that the data will primarily be used on the CPU.
@ HostAndDeviceMostlyRead
Indicates that the data will be used both on the accelerator and on the CPU and will not be frequentl...
@ ManagedMemoryDevice
The memory is managed memory on the accelerator.
@ Host
The memory is on the host.
@ ManagedMemoryHost
The memory is managed memory on the host.
@ Device
The memory is on the accelerator.
@ HostPinned
Allocates on the host.
@ Unknown
Unknown or uninitialized value.
@ Host
Allocates on the host.
@ UnifiedMemory
Allocates using unified memory.
@ Device
Allocates on the device.
Namespace of Arccore.