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