Arcane  4.2.1.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
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 }
238 {
239 UniqueArray<IntSubClass> c{ 5, 7 };
240 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
241 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
242 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
243 }
244 {
245 SharedArray<IntSubClass> c{ 5, 7 };
246 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
247 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
248 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
249 }
250 {
251 PrintableMemoryAllocator allocator;
252 UniqueArray<IntSubClass> c(&allocator);
253 UniqueArray<IntSubClass> cx(&allocator, 5);
254 ARCCORE_UT_CHECK((cx.size() == 5), "Bad value [5]");
255 c.add(5);
256 c.add(7);
258 c2.add(3);
259 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
260 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
261 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
262 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
263 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
264 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
265 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
266 for (Integer i = 0; i < 50; ++i)
267 c.add(i + 3);
268 c.resize(24);
269 c.reserve(70);
270 }
271 {
273 c2.add(3);
274 c2.add(5);
276 ASSERT_EQ(c22.size(), 33);
277 c22 = c2;
278 {
280 c.add(5);
281 c.add(7);
282 c2 = c;
285 c2.resize(125);
286 ASSERT_EQ(c2.size(), c3.size());
287 ASSERT_EQ(c2.size(), c4.size());
288 c3.resize(459);
289 ASSERT_EQ(c2.size(), c3.size());
290 ASSERT_EQ(c2.size(), c4.size());
291 c4.resize(932);
292 c.resize(32);
293 }
294 c2.add(3);
295 ARCCORE_UT_CHECK((c2.size() == 33), "Bad value [3]");
296 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
297 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
298 ARCCORE_UT_CHECK((c2[32] == 3), "Bad value [7]");
299 c2.resize(1293);
300 ASSERT_EQ(c2.size(), 1293);
301 ASSERT_EQ(c22.size(), 2);
302
303 {
304 SharedArray<IntSubClass> values1 = { -7, 3, 4 };
305 ASSERT_EQ(values1.size(), 3);
306 ASSERT_EQ(values1[0], -7);
307 ASSERT_EQ(values1[1], 3);
308 ASSERT_EQ(values1[2], 4);
309 values1 = { 2, -1, 9, 13 };
310 ASSERT_EQ(values1.size(), 4);
311 ASSERT_EQ(values1[0], 2);
312 ASSERT_EQ(values1[1], -1);
313 ASSERT_EQ(values1[2], 9);
314 ASSERT_EQ(values1[3], 13);
315 SharedArray<IntSubClass> values2 = values1;
316 ASSERT_EQ(values2, values1);
317
318 values1 = {};
319 ASSERT_EQ(values1.size(), 0);
320 ASSERT_EQ(values2.size(), 0);
321 }
322 }
323 {
324 UniqueArray<Int32> values1 = { 2, 5 };
325 UniqueArray<Int32> values2 = { 4, 9, 7 };
326 // Copie les valeurs de values2 à la fin de values1.
327 std::copy(std::begin(values2), std::end(values2), std::back_inserter(values1));
328 std::cout << "** VALUES1 = " << values1 << "\n";
329 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
330 ARCCORE_UT_CHECK((values1[0] == 2), "BI: Bad value [0]");
331 ARCCORE_UT_CHECK((values1[1] == 5), "BI: Bad value [1]");
332 ARCCORE_UT_CHECK((values1[2] == 4), "BI: Bad value [2]");
333 ARCCORE_UT_CHECK((values1[3] == 9), "BI: Bad value [3]");
334 ARCCORE_UT_CHECK((values1[4] == 7), "BI: Bad value [4]");
335
337 vx.add(IntPtrSubClass(5));
338 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
340 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
341
342 values1 = { -7, 3 };
343 ASSERT_EQ(values1.size(), 2);
344 ASSERT_EQ(values1[0], -7);
345 ASSERT_EQ(values1[1], 3);
346
347 values1 = {};
348 ASSERT_EQ(values1.size(), 0);
349 }
350 {
351 UniqueArray<Int32> values1;
352 UniqueArray<Int32> values2 = { 4, 9, 7, 6, 3 };
353 // Copie les valeurs de values2 à la fin de values1.
354 values1.copy(values2);
355 std::cout << "** VALUES1 = " << values1 << "\n";
356 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
357 ARCCORE_UT_CHECK((values1[0] == 4), "BI2: Bad value [0]");
358 ARCCORE_UT_CHECK((values1[1] == 9), "BI2: Bad value [1]");
359 ARCCORE_UT_CHECK((values1[2] == 7), "BI2: Bad value [2]");
360 ARCCORE_UT_CHECK((values1[3] == 6), "BI2: Bad value [3]");
361 ARCCORE_UT_CHECK((values1[4] == 3), "BI2: Bad value [4]");
362
364 vx.add(IntPtrSubClass(5));
365 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
367 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
368 }
369 {
371 vx.add(IntPtrSubClass(5));
374 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
377 std::cout << "V=" << cicvx->m_v << '\n';
378 }
379 {
381 vx.add(IntPtrSubClass(5));
382 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
383 UniqueArray<IntPtrSubClass>::iterator iend = std::end(vx);
385 std::cout << "V=" << i->m_v << " " << ci->m_v << " " << (iend - i) << '\n';
387 UniqueArray<IntPtrSubClass>::const_iterator cicvx = std::begin(cvx);
388 std::cout << "V=" << cicvx->m_v << '\n';
389 std::copy(std::begin(vx), std::end(vx), std::begin(vx));
390 }
391 {
392 UniqueArray<Int32> values = { 4, 9, 7 };
393 for (typename ArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
394 std::cout << *i << '\n';
395 }
396 for (typename ConstArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
397 std::cout << *i << '\n';
398 }
399 for (auto i : values.range()) {
400 std::cout << i << '\n';
401 }
402 for (auto i : values.constView().range()) {
403 std::cout << i << '\n';
404 }
405
406 {
407 auto r1 = std::make_reverse_iterator(values.end());
408 auto r2 = std::make_reverse_iterator(values.begin());
409 for (; r1 != r2; ++r1) {
410 std::cout << "RVALUE = " << *r1 << '\n';
411 }
412 }
413 {
414 auto r1 = values.rbegin();
415 ASSERT_EQ((*r1), 7);
416 ++r1;
417 ASSERT_EQ((*r1), 9);
418 ++r1;
419 ASSERT_EQ((*r1), 4);
420 ++r1;
421 ASSERT_TRUE((r1 == values.rend()));
422 }
423 {
426 c2.add(IntSubClassNoPod{ 3 });
427 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
428 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
429 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
430 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
431 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
432 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
433 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
434 c = c2.span();
435 SmallSpan<const IntSubClassNoPod> c2_small_span = c2;
436 ASSERT_EQ(c.constSpan(), c2.constSpan());
437 ASSERT_EQ(c.constSmallSpan(), c2_small_span);
438 ASSERT_EQ(c.smallSpan(), c2.smallSpan());
439 }
440 }
441}
442} // namespace
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
446
447TEST(Array, Misc)
448{
449 try {
450 _testArrayNewInternal();
451 }
452 catch (const Exception& ex) {
453 std::cerr << "Exception ex=" << ex << "\n";
454 throw;
455 }
456}
457
458/*---------------------------------------------------------------------------*/
459/*---------------------------------------------------------------------------*/
460
461namespace
462{
463void _Add(Array<Real>& v, Integer new_size)
464{
465 v.resize(new_size);
466}
467} // namespace
468
469/*---------------------------------------------------------------------------*/
470/*---------------------------------------------------------------------------*/
471
472TEST(Array, Misc2)
473{
474 using namespace Arccore;
475 {
477 v.resize(3);
478 v[0] = 1.2;
479 v.at(1) = -1.3;
480 v[2] = 7.6;
481 ASSERT_EQ(v[0], 1.2);
482 ASSERT_EQ(v[1], -1.3);
483 ASSERT_EQ(v.at(2), 7.6);
484
485 v.add(4.3);
486 for (Real x : v) {
487 std::cout << " Value: " << x << '\n';
488 }
489 v.printInfos(std::cout);
490 }
491 {
493 v.add(4.3);
494 v.add(5.3);
495 v.add(4.6);
496 v.printInfos(std::cout);
497 v.add(14.3);
498 v.add(25.3);
499 v.add(34.6);
500 v.printInfos(std::cout);
501 v.resize(4);
502 v.printInfos(std::cout);
503 v.add(12.2);
504 v.add(2.4);
505 v.add(3.4);
506 v.add(3.6);
507 v.printInfos(std::cout);
508 for (Integer i = 0, is = v.size(); i < is; ++i) {
509 std::cout << " Value: " << v[i] << '\n';
510 }
511 }
512 {
514 v.reserve(5);
515 for (int i = 0; i < 10; ++i)
516 v.add((Real)i);
517 for (Integer i = 0, is = v.size(); i < is; ++i) {
518 std::cout << " Value: " << v[i] << '\n';
519 }
520 }
521 {
523 v.reserve(175);
524 for (int i = 0; i < 27500; ++i) {
525 Real z = (Real)i;
526 v.add(z * z);
527 }
528 for (int i = 0; i < 5000; ++i) {
529 v.remove(i * 2);
530 }
531 v.reserve(150);
532 for (int i = 0; i < 27500; ++i) {
533 Real z = (Real)i;
534 v.add(z * z);
535 }
536 std::cout << " ValueSize= " << v.size() << " values=" << v << '\n';
537 }
538 for (Integer i = 0; i < 100; ++i) {
540 _Add(v, 500000);
541 _Add(v, 1000000);
542 _Add(v, 0);
543 _Add(v, 100000);
544 _Add(v, 0);
545 _Add(v, 0);
546 _Add(v, 230000);
547 std::cout << " Size: " << v.size() << '\n';
548 ASSERT_EQ(v.size(), 230000);
549 }
550}
551
552/*---------------------------------------------------------------------------*/
553/*---------------------------------------------------------------------------*/
554
555TEST(Array, SubViews)
556{
557 using namespace Arccore;
558
559 {
560 // Test Array::subView() et Array::subConstView()
562 v.resize(23);
563 for (Int32 i = 0, n = v.size(); i < n; ++i)
564 v[i] = (i + 1);
565
566 auto sub_view1 = v.subView(50, 5);
567 ASSERT_EQ(sub_view1.data(), nullptr);
568 ASSERT_EQ(sub_view1.size(), 0);
569
570 auto sub_view2 = v.subView(2, 8);
571 ASSERT_EQ(sub_view2.size(), 8);
572 for (Int32 i = 0, n = sub_view2.size(); i < n; ++i)
573 ASSERT_EQ(sub_view2[i], v[2 + i]);
574
575 auto sub_view3 = v.subView(20, 8);
576 ASSERT_EQ(sub_view3.size(), 3);
577 for (Int32 i = 0, n = sub_view3.size(); i < n; ++i)
578 ASSERT_EQ(sub_view3[i], v[20 + i]);
579
580 auto sub_const_view1 = v.subConstView(50, 5);
581 ASSERT_EQ(sub_const_view1.data(), nullptr);
582 ASSERT_EQ(sub_const_view1.size(), 0);
583
584 auto sub_const_view2 = v.subConstView(2, 8);
585 ASSERT_EQ(sub_const_view2.size(), 8);
586 for (Int32 i = 0, n = sub_const_view2.size(); i < n; ++i)
587 ASSERT_EQ(sub_const_view2[i], v[2 + i]);
588
589 auto sub_const_view3 = v.subConstView(20, 8);
590 ASSERT_EQ(sub_const_view3.size(), 3);
591 for (Int32 i = 0, n = sub_const_view3.size(); i < n; ++i)
592 ASSERT_EQ(sub_const_view3[i], v[20 + i]);
593 }
594}
595
596/*---------------------------------------------------------------------------*/
597/*---------------------------------------------------------------------------*/
598
599class NoCopyData
600{
601 public:
602
603 NoCopyData(const NoCopyData& x) = delete;
604};
605
606template <typename DataType>
608: public Arccore::Array<DataType>
609{
610 public:
611
612 using BaseClass = Arccore::Array<DataType>;
613};
614
615/*---------------------------------------------------------------------------*/
616/*---------------------------------------------------------------------------*/
617
618TEST(Array, Misc3)
619{
620 using namespace Arccore;
621
622 {
624 const Int32 ref_value1 = 12;
625 const Int32 ref_value2 = 7;
626
627 c.resize(9, IntSubClassNoPod(ref_value1));
628 std::cout << "C1=" << c << "\n";
629 for (IntSubClassNoPod x : c)
630 ASSERT_EQ(x, ref_value1);
631
632 c.resize(21, IntSubClassNoPod(ref_value2));
633 ASSERT_EQ(c.size(), 21);
634 std::cout << "C2=" << c << "\n";
635
636 // Redimensionne sans initialiser. Les valeurs pour les éléments
637 // de 9 à 18 doivent valoir \a ref_value2
638 c.resizeNoInit(18);
639 std::cout << "C4=" << c << "\n";
640 for (Int32 i = 9, s = c.size(); i < s; ++i)
641 ASSERT_EQ(c[i], ref_value2);
642 for (Int32 i = 9, s = c.size(); i < s; ++i)
643 new (c.data() + i) IntSubClassNoPod(i + 2);
644 for (Int32 i = 9, s = c.size(); i < s; ++i)
645 ASSERT_EQ(c[i], (i + 2));
646 }
647 {
649 c2.resizeNoInit(25);
650 }
651}
652
653/*---------------------------------------------------------------------------*/
654/*---------------------------------------------------------------------------*/
655
656template <typename ArrayType>
658{
659 public:
660
661 static void doTestBase()
662 {
663 using namespace Arccore;
664
666 PrintableMemoryAllocator printable_allocator2;
667 IMemoryAllocator* allocator2 = &printable_allocator2;
668
669 {
670 std::cout << "Array a\n";
671 ArrayType a(allocator1);
672 ASSERT_EQ(a.allocator(), allocator1);
673 a.add(27);
674 a.add(38);
675 a.add(13);
676 a.add(-5);
677
678 std::cout << "Array b\n";
679 ArrayType b(allocator2);
680 ASSERT_EQ(b.capacity(), 0);
681 ASSERT_EQ(b.size(), 0);
682 ASSERT_EQ(b.allocator(), allocator2);
683
684 b = a;
685 ASSERT_EQ(b.size(), a.size());
686 ASSERT_EQ(b.allocator(), a.allocator());
687
688 std::cout << "Array c\n";
689 ArrayType c(a.clone());
690 ASSERT_EQ(c.allocator(), a.allocator());
691 ASSERT_EQ(c.size(), a.size());
692 ASSERT_EQ(c.constSpan(), a.constSpan());
693
694 std::cout << "Array d\n";
695 ArrayType d(allocator2, a);
696 ASSERT_EQ(d.allocator(), allocator2);
697 ASSERT_EQ(d.size(), a.size());
698 ASSERT_EQ(d.constSpan(), a.constSpan());
699
700 std::cout << "Array e\n";
701 ArrayType e(allocator2, 25);
702 ASSERT_EQ(e.allocator(), allocator2);
703 ASSERT_EQ(e.size(), 25);
704
705 ArrayType f(allocator2);
706 f = e;
707 ASSERT_EQ(f.allocator(), e.allocator());
708 ASSERT_EQ(f.size(), e.size());
709
710 f = f;
711 ASSERT_EQ(f.allocator(), e.allocator());
712 ASSERT_EQ(f.size(), e.size());
713 }
714 }
715};
716
717TEST(UniqueArray, AllocatorBase)
718{
720}
721
722TEST(SharedArray, AllocatorBase)
723{
725}
726
727/*---------------------------------------------------------------------------*/
728/*---------------------------------------------------------------------------*/
729
731{
732 using namespace Arccore;
733 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
734 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
735 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
736 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
737
738 PrintableMemoryAllocator printable_allocator;
739 PrintableMemoryAllocator printable_allocator2;
742 {
743 std::cout << "Array a1\n";
744 UniqueArray<Int32> a1(allocator2);
745 ASSERT_EQ(a1.allocator(), allocator2);
746 ASSERT_EQ(a1.size(), 0);
747 ASSERT_EQ(a1.capacity(), 0);
748 ASSERT_EQ(a1.data(), nullptr);
749
750 std::cout << "Array a2\n";
751 UniqueArray<Int32> a2(a1);
752 ASSERT_EQ(a1.allocator(), a2.allocator());
753 ASSERT_EQ(a2.capacity(), 0);
754 ASSERT_EQ(a2.data(), nullptr);
755 a1.reserve(3);
756 a1.add(5);
757 a1.add(7);
758 a1.add(12);
759 a1.add(3);
760 a1.add(1);
761 ASSERT_EQ(a1.size(), 5);
762
763 std::cout << "Array a3\n";
764 UniqueArray<Int32> a3(allocator1);
765 a3.add(4);
766 a3.add(6);
767 a3.add(2);
768 ASSERT_EQ(a3.size(), 3);
769 a3 = a1;
770 ASSERT_EQ(a3.allocator(), a1.allocator());
771 ASSERT_EQ(a3.size(), a1.size());
772 ASSERT_EQ(a3.constSpan(), a1.constSpan());
773
774 std::cout << "Array a4\n";
775 UniqueArray<Int32> a4(allocator1);
776 a4.add(4);
777 a4.add(6);
778 a4.add(2);
779 ASSERT_EQ(a4.size(), 3);
780 a4 = a1.span();
781 ASSERT_EQ(a4.allocator(), allocator1);
782
783 a4 = UniqueArray<Int32>(&printable_allocator2);
784
785 UniqueArray<Int32> array[2];
786 IMemoryAllocator* allocator3 = allocator1;
787 for (Integer i = 0; i < 2; ++i) {
788 array[i] = UniqueArray<Int32>(allocator3);
789 }
790 ASSERT_EQ(array[0].allocator(), allocator3);
791 ASSERT_EQ(array[1].allocator(), allocator3);
792 }
793}
794
795/*---------------------------------------------------------------------------*/
796/*---------------------------------------------------------------------------*/
797
799{
800 using namespace Arccore;
801 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
802 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
803 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
804 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
805
806 PrintableMemoryAllocator printable_allocator;
807 PrintableMemoryAllocator printable_allocator2;
810 {
811 std::cout << "Array a1\n";
812 SharedArray<Int32> a1(allocator2);
813 ASSERT_EQ(a1.allocator(), allocator2);
814 ASSERT_EQ(a1.size(), 0);
815 ASSERT_EQ(a1.capacity(), 0);
816 ASSERT_EQ(a1.data(), nullptr);
817
818 std::cout << "Array a2\n";
819 SharedArray<Int32> a2(a1);
820 ASSERT_EQ(a1.allocator(), a2.allocator());
821 ASSERT_EQ(a2.capacity(), 0);
822 ASSERT_EQ(a2.data(), nullptr);
823 a1.reserve(3);
824 a1.add(5);
825 a1.add(7);
826 a1.add(12);
827 a1.add(3);
828 a1.add(1);
829 ASSERT_EQ(a1.size(), 5);
830
831 std::cout << "Array a3\n";
833 a3.add(4);
834 a3.add(6);
835 a3.add(2);
836 ASSERT_EQ(a3.size(), 3);
837 a3 = a1;
838 ASSERT_EQ(a3.allocator(), a1.allocator());
839 ASSERT_EQ(a3.size(), a1.size());
840 ASSERT_EQ(a3.constSpan(), a1.constSpan());
841
842 std::cout << "Array a4\n";
843 SharedArray<Int32> a4(allocator1, 2);
844 ASSERT_EQ(a4.size(), 2);
845 a4.add(4);
846 a4.add(6);
847 a4.add(2);
848 ASSERT_EQ(a4.size(), 5);
849 ASSERT_EQ(a4[2], 4);
850 ASSERT_EQ(a4[3], 6);
851 ASSERT_EQ(a4[4], 2);
852
853 a4 = a1.span();
854 ASSERT_EQ(a4.allocator(), allocator1);
855
856 a4 = SharedArray<Int32>(&printable_allocator2);
857
858 SharedArray<Int32> array[2];
859 IMemoryAllocator* allocator3 = allocator1;
860 for (Integer i = 0; i < 2; ++i) {
861 array[i] = SharedArray<Int32>(allocator3);
862 }
863 ASSERT_EQ(array[0].allocator(), allocator3);
864 ASSERT_EQ(array[1].allocator(), allocator3);
865 }
866}
867
876: public IMemoryAllocator3
877{
878 public:
879
880 bool hasRealloc(MemoryAllocationArgs args) const override
881 {
882 _checkValid(args);
883 return m_default_allocator.hasRealloc(args);
884 }
885 AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
886 {
887 _checkValid(args);
888 return m_default_allocator.allocate(args, new_size);
889 }
890 AllocatedMemoryInfo reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size) override
891 {
892 _checkValid(args);
893 return m_default_allocator.reallocate(args, current_ptr, new_size);
894 }
895 void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo ptr) override
896 {
897 _checkValid(args);
898 m_default_allocator.deallocate(args, ptr);
899 }
900 Int64 adjustedCapacity(MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const override
901 {
902 _checkValid(args);
903 return m_default_allocator.adjustedCapacity(args, wanted_capacity, element_size);
904 }
905 size_t guaranteedAlignment(MemoryAllocationArgs args) const override
906 {
907 _checkValid(args);
908 return m_default_allocator.guaranteedAlignment(args);
909 }
910
911 void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr) override
912 {
913 // Cette méthode n'est appelée qu'une seule fois donc on teste directement les valeurs attendues
914 ASSERT_EQ(old_args.memoryLocationHint(), eMemoryLocationHint::None);
915 ASSERT_EQ(new_args.memoryLocationHint(), eMemoryLocationHint::MainlyHost);
916 ASSERT_EQ(ptr.size(), 8);
917 m_default_allocator.notifyMemoryArgsChanged(old_args, new_args, ptr);
918 }
919
920 private:
921
922 DefaultMemoryAllocator3 m_default_allocator;
923
924 private:
925
926 static void _checkValid(MemoryAllocationArgs args)
927 {
928 bool v1 = args.memoryLocationHint() == eMemoryLocationHint::None;
929 bool v2 = args.memoryLocationHint() == eMemoryLocationHint::MainlyHost;
930 bool v3 = args.memoryLocationHint() == eMemoryLocationHint::HostAndDeviceMostlyRead;
931 bool is_valid = v1 || v2 || v3;
932 ASSERT_TRUE(is_valid);
933 }
934};
935
936#define ASSERT_SAME_ARRAY_INFOS(a, b) \
937 ASSERT_EQ(a.allocationOptions(), b.allocationOptions()); \
938 ASSERT_EQ(a.size(), b.size()); \
939 ASSERT_EQ(a.capacity(), b.capacity())
940
941TEST(Array, AllocatorV2)
942{
943 using namespace Arccore;
944 TesterMemoryAllocatorV3 testerv2_allocator;
945 TesterMemoryAllocatorV3 testerv2_allocator2;
946 MemoryAllocationOptions allocate_options1(&testerv2_allocator, eMemoryLocationHint::HostAndDeviceMostlyRead);
947 MemoryAllocationOptions allocate_options2(&testerv2_allocator, eMemoryLocationHint::None, 0);
948 {
949 MemoryAllocationOptions opt3(&testerv2_allocator);
950 opt3.setMemoryLocationHint(eMemoryLocationHint::HostAndDeviceMostlyRead);
951 ASSERT_EQ(opt3, allocate_options1);
952 }
953 {
954 std::cout << "Array a1\n";
955 UniqueArray<Int32> a1(allocate_options2);
956 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
957 ASSERT_EQ(a1.size(), 0);
958 ASSERT_EQ(a1.capacity(), 0);
959 ASSERT_EQ(a1.data(), nullptr);
960
961 std::cout << "Array a2\n";
962 UniqueArray<Int32> a2(a1);
963 ASSERT_SAME_ARRAY_INFOS(a2, a1);
964 ASSERT_EQ(a2.data(), nullptr);
965 a1.reserve(3);
966 a1.add(5);
967 a1.add(7);
968 a1.add(12);
969 a1.add(3);
970 a1.add(1);
971 ASSERT_EQ(a1.size(), 5);
972 a2.add(9);
973 a2.add(17);
974 // Pour tester notifyMemoryArgsChanged()
975 a2.setMemoryLocationHint(eMemoryLocationHint::MainlyHost);
976
977 std::cout << "Array a3\n";
978 UniqueArray<Int32> a3(allocate_options1);
979 a3.add(4);
980 a3.add(6);
981 a3.add(2);
982 ASSERT_EQ(a3.size(), 3);
983 a3 = a1;
984 ASSERT_EQ(a3.allocator(), a1.allocator());
985 ASSERT_EQ(a3.size(), a1.size());
986 ASSERT_EQ(a3.constSpan(), a1.constSpan());
987
988 std::cout << "Array a4\n";
989 UniqueArray<Int32> a4(allocate_options1);
990 a4.add(4);
991 a4.add(6);
992 a4.add(2);
993 ASSERT_EQ(a4.size(), 3);
994 a4 = a1.span();
995 ASSERT_EQ(a4.allocationOptions(), allocate_options1);
996
997 a4 = UniqueArray<Int32>(&testerv2_allocator2);
998
999 UniqueArray<Int32> array[2];
1000 MemoryAllocationOptions allocator3 = allocate_options1;
1001 for (Integer i = 0; i < 2; ++i) {
1002 array[i] = UniqueArray<Int32>(allocator3);
1003 }
1004 ASSERT_EQ(array[0].allocationOptions(), allocator3);
1005 ASSERT_EQ(array[1].allocationOptions(), allocator3);
1006 }
1007}
1008
1009/*---------------------------------------------------------------------------*/
1010/*---------------------------------------------------------------------------*/
1011
1012TEST(Array, DebugInfo)
1013{
1014 using namespace Arccore;
1015 DefaultMemoryAllocator3 m_default_allocator;
1016 MemoryAllocationOptions allocate_options2(&m_default_allocator, eMemoryLocationHint::None, 0);
1017
1018 String a1_name("Array1");
1019 String sa1_name("SharedArray1");
1021 {
1022 std::cout << "Array a1\n";
1023 UniqueArray<Int32> a1(allocate_options2);
1024 a1.setDebugName(a1_name);
1025 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
1026 ASSERT_EQ(a1.size(), 0);
1027 ASSERT_EQ(a1.capacity(), 0);
1028 ASSERT_EQ(a1.data(), nullptr);
1029 ASSERT_EQ(a1.debugName(), a1_name);
1030
1031 std::cout << "SharedArray sa1\n";
1032 SharedArray<Int32> sa1(allocate_options2);
1033 sa1.setDebugName(sa1_name);
1034 ASSERT_EQ(sa1.allocationOptions(), allocate_options2);
1035 ASSERT_EQ(sa1.size(), 0);
1036 ASSERT_EQ(sa1.capacity(), 0);
1037 ASSERT_EQ(sa1.data(), nullptr);
1038 ASSERT_EQ(sa1.debugName(), sa1_name);
1039
1040 ASSERT_EQ(a1.debugName(), a1_name);
1041
1042 std::cout << "Array a2\n";
1043 UniqueArray<Int32> a2(a1);
1044 ASSERT_SAME_ARRAY_INFOS(a2, a1);
1045 ASSERT_EQ(a2.data(), nullptr);
1046 ASSERT_EQ(a2.debugName(), a1_name);
1047 a1.reserve(3);
1048 a1.add(5);
1049 a1.add(7);
1050 a1.add(12);
1051 a1.add(3);
1052 a1.add(1);
1053 ASSERT_EQ(a1.size(), 5);
1054 a2.add(9);
1055 a2.add(17);
1056 ASSERT_EQ(a2.debugName(), a1_name);
1057 ASSERT_EQ(a2.size(), 2);
1058
1059 a3 = a2;
1060 }
1061 ASSERT_EQ(a3.debugName(), a1_name);
1062 ASSERT_EQ(a3.size(), 2);
1063}
1064
1065/*---------------------------------------------------------------------------*/
1066/*---------------------------------------------------------------------------*/
1067
1068TEST(Collections, Memory)
1069{
1070 using namespace Arccore;
1071 std::cout << eHostDeviceMemoryLocation::Unknown << " "
1076
1077 std::cout << eMemoryResource::Unknown << " "
1078 << eMemoryResource::Host << " "
1080 << eMemoryResource::Device << " "
1082
1087}
1088
1089/*---------------------------------------------------------------------------*/
1090/*---------------------------------------------------------------------------*/
1091
1092namespace Arcane
1093{
1094// Instancie explicitement les classes tableaux pour garantir
1095// que toutes les méthodes fonctionnent
1096template class UniqueArray<IntSubClass>;
1097template class SharedArray<IntSubClass>;
1098template class Array<IntSubClass>;
1099template class AbstractArray<IntSubClass>;
1100} // namespace Arcane
#define ASSERT_TRUE(condition)
Vérifie que condition est vrai.
Definition Assertion.h:125
String debugName() const
Nom de debug (nul si aucun nom spécifié).
Classe abstraite de base d'un vecteur.
void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location)
Positionne l'emplacement physique de la zone mémoire.
Integer size() const
Nombre d'éléments du vecteur.
ArrayIterator< pointer > iterator
Type de l'itérateur sur un élément du tableau.
eHostDeviceMemoryLocation hostDeviceMemoryLocation() const
Positionne l'emplacement physique de la zone mémoire.
ArrayIterator< const_pointer > const_iterator
Type de l'itérateur constant sur un élément du tableau.
static constexpr Integer simdAlignment()
Alignement pour les structures utilisant la vectorisation.
static AlignedMemoryAllocator * Simd()
Allocateur garantissant l'alignement pour utiliser la vectorisation sur la plateforme cible.
Informations sur une zone mémoire allouée.
Int64 size() const
Taille en octets de la zone mémoire utilisée. (-1) si inconnue.
Meta-Données des tableaux.
ConstIterT< ArrayView< T > > const_iter
Type d'un itérateur constant sur tout le tableau.
Tableau d'items de types quelconques.
iterator end()
Itérateur sur le premier élément après la fin du tableau.
ConstArrayView< T > constView() const
Vue constante sur ce tableau.
void remove(Int64 index)
Supprime l'entité ayant l'indice index.
void resize(Int64 s)
Change le nombre d'éléments du tableau à s.
ArrayView< T > subView(Int64 abegin, Integer asize)
Sous-vue à partir de l'élément abegin et contenant asize éléments.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
reverse_iterator rbegin()
Itérateur inverse sur le premier élément du tableau.
T & at(Int64 i)
Elément d'indice i. Vérifie toujours les débordements.
void resizeNoInit(Int64 s)
Redimensionne sans initialiser les nouvelles valeurs.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sous-vue à partir de l'élément abegin et contenant asize éléments.
SmallSpan< const T > smallSpan() const
Vue immutable sur ce tableau.
SmallSpan< const T > constSmallSpan() const
Vue immutable sur ce tableau.
void copy(Span< const T > rhs)
Copie les valeurs de rhs dans l'instance.
ArrayView< T > view() const
Vue mutable sur ce tableau.
Span< const T > span() const
Vue immutable sur ce tableau.
reverse_iterator rend()
Itérateur inverse sur le premier élément après la fin du tableau.
iterator begin()
Itérateur sur le premier élément du tableau.
Span< const T > constSpan() const
Vue constante sur ce tableau.
ArrayRange< pointer > range()
Intervalle d'itération du premier au dernièr élément.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
ConstIterT< ConstArrayView< T > > const_iter
Type d'un itérateur constant sur tout le tableau.
Classe de base d'une exception.
Interface d'un allocateur pour la mémoire.
Classe contenant des informations pour spécialiser les allocations.
Allocateur mémoire via malloc/realloc/free avec impression listing.
Vecteur 1D de données avec sémantique par référence.
SharedArray< T > clone() const
Clone le tableau.
Vue d'un tableau d'éléments de type T.
Definition Span.h:802
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
Allocateur pour tester les arguments.
Definition TestArray.cc:877
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)
Échange les valeurs de v1 et v2.
Int32 Integer
Type représentant un entier.
@ MainlyHost
Indique que la donnée sera plutôt utilisée sur CPU.
@ HostAndDeviceMostlyRead
Indique que la donnée sera utilisée à la fois sur accélérateur et sur CPU et qu'elle ne sera pas souv...
@ Unknown
Localisation inconnue.
@ ManagedMemoryDevice
La mémoire est de la mémoire managée sur accélérateur.
@ Host
La mémoire est sur l'hôte.
@ ManagedMemoryHost
La mémoire est de la mémoire managée sur l'hôte.
@ Device
La mémoire est sur accélérateur.
@ HostPinned
Alloue sur l'hôte.
@ Unknown
Valeur inconnue ou non initialisée.
@ Host
Alloue sur l'hôte.
@ UnifiedMemory
Alloue en utilisant la mémoire unifiée.
@ Device
Alloue sur le device.
Espace de nom de Arccore.