Arcane  v3.15.0.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-2024 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 {
326 UniqueArray<Int32> values1 = { 2, 5 };
327 UniqueArray<Int32> values2 = { 4, 9, 7 };
328 // Copie les valeurs de values2 à la fin de values1.
329 std::copy(std::begin(values2), std::end(values2), std::back_inserter(values1));
330 std::cout << "** VALUES1 = " << values1 << "\n";
331 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
332 ARCCORE_UT_CHECK((values1[0] == 2), "BI: Bad value [0]");
333 ARCCORE_UT_CHECK((values1[1] == 5), "BI: Bad value [1]");
334 ARCCORE_UT_CHECK((values1[2] == 4), "BI: Bad value [2]");
335 ARCCORE_UT_CHECK((values1[3] == 9), "BI: Bad value [3]");
336 ARCCORE_UT_CHECK((values1[4] == 7), "BI: Bad value [4]");
337
339 vx.add(IntPtrSubClass(5));
340 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
342 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
343
344 values1 = { -7, 3 };
345 ASSERT_EQ(values1.size(),2);
346 ASSERT_EQ(values1[0],-7);
347 ASSERT_EQ(values1[1],3);
348
349 values1 = {};
350 ASSERT_EQ(values1.size(),0);
351 }
352 {
353 UniqueArray<Int32> values1;
354 UniqueArray<Int32> values2 = { 4, 9, 7, 6, 3 };
355 // Copie les valeurs de values2 à la fin de values1.
356 values1.copy(values2);
357 std::cout << "** VALUES1 = " << values1 << "\n";
358 ARCCORE_UT_CHECK((values1.size() == 5), "BI: Bad size");
359 ARCCORE_UT_CHECK((values1[0] == 4), "BI2: Bad value [0]");
360 ARCCORE_UT_CHECK((values1[1] == 9), "BI2: Bad value [1]");
361 ARCCORE_UT_CHECK((values1[2] == 7), "BI2: Bad value [2]");
362 ARCCORE_UT_CHECK((values1[3] == 6), "BI2: Bad value [3]");
363 ARCCORE_UT_CHECK((values1[4] == 3), "BI2: Bad value [4]");
364
366 vx.add(IntPtrSubClass(5));
367 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
369 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
370 }
371 {
373 vx.add(IntPtrSubClass(5));
376 std::cout << "V=" << i->m_v << " " << ci->m_v << '\n';
379 std::cout << "V=" << cicvx->m_v << '\n';
380 }
381 {
383 vx.add(IntPtrSubClass(5));
384 UniqueArray<IntPtrSubClass>::iterator i = std::begin(vx);
385 UniqueArray<IntPtrSubClass>::iterator iend = std::end(vx);
387 std::cout << "V=" << i->m_v << " " << ci->m_v << " " << (iend - i) << '\n';
389 UniqueArray<IntPtrSubClass>::const_iterator cicvx = std::begin(cvx);
390 std::cout << "V=" << cicvx->m_v << '\n';
391 std::copy(std::begin(vx), std::end(vx), std::begin(vx));
392 }
393 {
394 UniqueArray<Int32> values = { 4, 9, 7 };
395 for (typename ArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
396 std::cout << *i << '\n';
397 }
398 for (typename ConstArrayView<Int32>::const_iter i(values.view()); i(); ++i) {
399 std::cout << *i << '\n';
400 }
401 for (auto i : values.range()) {
402 std::cout << i << '\n';
403 }
404 for (auto i : values.constView().range()) {
405 std::cout << i << '\n';
406 }
407
408 {
409 auto r1 = std::make_reverse_iterator(values.end());
410 auto r2 = std::make_reverse_iterator(values.begin());
411 for (; r1 != r2; ++r1) {
412 std::cout << "RVALUE = " << *r1 << '\n';
413 }
414 }
415 {
416 auto r1 = values.rbegin();
417 ASSERT_EQ((*r1), 7);
418 ++r1;
419 ASSERT_EQ((*r1), 9);
420 ++r1;
421 ASSERT_EQ((*r1), 4);
422 ++r1;
423 ASSERT_TRUE((r1 == values.rend()));
424 }
425 {
428 c2.add(IntSubClassNoPod{ 3 });
429 ARCCORE_UT_CHECK((c2.size() == 3), "Bad value [3]");
430 ARCCORE_UT_CHECK((c.size() == 2), "Bad value [2]");
431 ARCCORE_UT_CHECK((c[0] == 5), "Bad value [5]");
432 ARCCORE_UT_CHECK((c[1] == 7), "Bad value [7]");
433 ARCCORE_UT_CHECK((c2[0] == 5), "Bad value [5]");
434 ARCCORE_UT_CHECK((c2[1] == 7), "Bad value [7]");
435 ARCCORE_UT_CHECK((c2[2] == 3), "Bad value [7]");
436 c = c2.span();
437 SmallSpan<const IntSubClassNoPod> c2_small_span = c2;
438 ASSERT_EQ(c.constSpan(), c2.constSpan());
439 ASSERT_EQ(c.constSmallSpan(), c2_small_span);
440 ASSERT_EQ(c.smallSpan(), c2.smallSpan());
441 }
442 }
443}
444} // namespace
445
446/*---------------------------------------------------------------------------*/
447/*---------------------------------------------------------------------------*/
448
449TEST(Array, Misc)
450{
451 try {
452 _testArrayNewInternal();
453 }
454 catch (const Exception& ex) {
455 std::cerr << "Exception ex=" << ex << "\n";
456 throw;
457 }
458}
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
462
463namespace
464{
465void
466_Add(Array<Real>& v,Integer new_size)
467{
468 v.resize(new_size);
469}
470}
471
472/*---------------------------------------------------------------------------*/
473/*---------------------------------------------------------------------------*/
474
475TEST(Array, Misc2)
476{
477 using namespace Arccore;
478 {
480 v.resize(3);
481 v[0] = 1.2;
482 v[1] = -1.3;
483 v[2] = 7.6;
484 v.add(4.3);
485 for (Real x : v) {
486 std::cout << " Value: " << x << '\n';
487 }
488 v.printInfos(std::cout);
489 }
490 {
492 v.add(4.3);
493 v.add(5.3);
494 v.add(4.6);
495 v.printInfos(std::cout);
496 v.add(14.3);
497 v.add(25.3);
498 v.add(34.6);
499 v.printInfos(std::cout);
500 v.resize(4);
501 v.printInfos(std::cout);
502 v.add(12.2);
503 v.add(2.4);
504 v.add(3.4);
505 v.add(3.6);
506 v.printInfos(std::cout);
507 for (Integer i = 0, is = v.size(); i < is; ++i) {
508 std::cout << " Value: " << v[i] << '\n';
509 }
510 }
511 {
513 v.reserve(5);
514 for (int i = 0; i < 10; ++i)
515 v.add((Real)i);
516 for (Integer i = 0, is = v.size(); i < is; ++i) {
517 std::cout << " Value: " << v[i] << '\n';
518 }
519 }
520 {
522 v.reserve(175);
523 for (int i = 0; i < 27500; ++i) {
524 Real z = (Real)i;
525 v.add(z * z);
526 }
527 for (int i = 0; i < 5000; ++i) {
528 v.remove(i * 2);
529 }
530 v.reserve(150);
531 for (int i = 0; i < 27500; ++i) {
532 Real z = (Real)i;
533 v.add(z * z);
534 }
535 std::cout << " ValueSize= " << v.size() << " values=" << v << '\n';
536 }
537 for (Integer i = 0; i < 100; ++i) {
539 _Add(v, 500000);
540 _Add(v, 1000000);
541 _Add(v, 0);
542 _Add(v, 100000);
543 _Add(v, 0);
544 _Add(v, 0);
545 _Add(v, 230000);
546 std::cout << " Size: " << v.size() << '\n';
547 ASSERT_EQ(v.size(), 230000);
548 }
549}
550
551/*---------------------------------------------------------------------------*/
552/*---------------------------------------------------------------------------*/
553
554TEST(Array, SubViews)
555{
556 using namespace Arccore;
557
558 {
559 // Test Array::subView() et Array::subConstView()
561 v.resize(23);
562 for (Int32 i = 0, n = v.size(); i < n; ++i)
563 v[i] = (i + 1);
564
565 auto sub_view1 = v.subView(50, 5);
566 ASSERT_EQ(sub_view1.data(), nullptr);
567 ASSERT_EQ(sub_view1.size(), 0);
568
569 auto sub_view2 = v.subView(2, 8);
570 ASSERT_EQ(sub_view2.size(), 8);
571 for (Int32 i = 0, n = sub_view2.size(); i < n; ++i)
572 ASSERT_EQ(sub_view2[i], v[2 + i]);
573
574 auto sub_view3 = v.subView(20, 8);
575 ASSERT_EQ(sub_view3.size(), 3);
576 for (Int32 i = 0, n = sub_view3.size(); i < n; ++i)
577 ASSERT_EQ(sub_view3[i], v[20 + i]);
578
579 auto sub_const_view1 = v.subConstView(50, 5);
580 ASSERT_EQ(sub_const_view1.data(), nullptr);
581 ASSERT_EQ(sub_const_view1.size(), 0);
582
583 auto sub_const_view2 = v.subConstView(2, 8);
584 ASSERT_EQ(sub_const_view2.size(), 8);
585 for (Int32 i = 0, n = sub_const_view2.size(); i < n; ++i)
586 ASSERT_EQ(sub_const_view2[i], v[2 + i]);
587
588 auto sub_const_view3 = v.subConstView(20, 8);
589 ASSERT_EQ(sub_const_view3.size(), 3);
590 for (Int32 i = 0, n = sub_const_view3.size(); i < n; ++i)
591 ASSERT_EQ(sub_const_view3[i], v[20 + i]);
592 }
593}
594
595/*---------------------------------------------------------------------------*/
596/*---------------------------------------------------------------------------*/
597
599{
600 public:
601 NoCopyData(const NoCopyData& x) = delete;
602};
603
604template <typename DataType>
606: public Arccore::Array<DataType>
607{
608 public:
609
611};
612
613/*---------------------------------------------------------------------------*/
614/*---------------------------------------------------------------------------*/
615
616TEST(Array, Misc3)
617{
618 using namespace Arccore;
619
620 {
622 const Int32 ref_value1 = 12;
623 const Int32 ref_value2 = 7;
624
625 c.resize(9, IntSubClassNoPod(ref_value1));
626 std::cout << "C1=" << c << "\n";
627 for (IntSubClassNoPod x : c)
628 ASSERT_EQ(x, ref_value1);
629
630 c.resize(21, IntSubClassNoPod(ref_value2));
631 ASSERT_EQ(c.size(), 21);
632 std::cout << "C2=" << c << "\n";
633
634 // Redimensionne sans initialiser. Les valeurs pour les éléments
635 // de 9 à 18 doivent valoir \a ref_value2
636 c.resizeNoInit(18);
637 std::cout << "C4=" << c << "\n";
638 for (Int32 i = 9, s = c.size(); i < s; ++i)
639 ASSERT_EQ(c[i], ref_value2);
640 for (Int32 i = 9, s = c.size(); i < s; ++i)
641 new (c.data() + i) IntSubClassNoPod(i + 2);
642 for (Int32 i = 9, s = c.size(); i < s; ++i)
643 ASSERT_EQ(c[i], (i + 2));
644 }
645 {
647 c2.resizeNoInit(25);
648 }
649}
650
651/*---------------------------------------------------------------------------*/
652/*---------------------------------------------------------------------------*/
653
654template<typename ArrayType>
656{
657 public:
658 static void doTestBase()
659 {
660 using namespace Arccore;
661
663 PrintableMemoryAllocator printable_allocator2;
664 IMemoryAllocator* allocator2 = &printable_allocator2;
665
666 {
667 std::cout << "Array a\n";
668 ArrayType a(allocator1);
669 ASSERT_EQ(a.allocator(),allocator1);
670 a.add(27);
671 a.add(38);
672 a.add(13);
673 a.add(-5);
674
675 std::cout << "Array b\n";
676 ArrayType b(allocator2);
677 ASSERT_EQ(b.capacity(),0);
678 ASSERT_EQ(b.size(),0);
679 ASSERT_EQ(b.allocator(),allocator2);
680
681 b = a;
682 ASSERT_EQ(b.size(),a.size());
683 ASSERT_EQ(b.allocator(),a.allocator());
684
685 std::cout << "Array c\n";
686 ArrayType c(a.clone());
687 ASSERT_EQ(c.allocator(),a.allocator());
688 ASSERT_EQ(c.size(),a.size());
689 ASSERT_EQ(c.constSpan(),a.constSpan());
690
691 std::cout << "Array d\n";
692 ArrayType d(allocator2,a);
693 ASSERT_EQ(d.allocator(),allocator2);
694 ASSERT_EQ(d.size(),a.size());
695 ASSERT_EQ(d.constSpan(),a.constSpan());
696
697 std::cout << "Array e\n";
698 ArrayType e(allocator2,25);
699 ASSERT_EQ(e.allocator(),allocator2);
700 ASSERT_EQ(e.size(),25);
701
702 ArrayType f(allocator2);
703 f = e;
704 ASSERT_EQ(f.allocator(),e.allocator());
705 ASSERT_EQ(f.size(),e.size());
706
707 f = f;
708 ASSERT_EQ(f.allocator(),e.allocator());
709 ASSERT_EQ(f.size(),e.size());
710 }
711 }
712};
713
714TEST(UniqueArray, AllocatorBase)
715{
717}
718
719TEST(SharedArray, AllocatorBase)
720{
722}
723
724/*---------------------------------------------------------------------------*/
725/*---------------------------------------------------------------------------*/
726
728{
729 using namespace Arccore;
730 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
731 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
732 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
733 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
734
735 PrintableMemoryAllocator printable_allocator;
736 PrintableMemoryAllocator printable_allocator2;
739 {
740 std::cout << "Array a1\n";
741 UniqueArray<Int32> a1(allocator2);
742 ASSERT_EQ(a1.allocator(), allocator2);
743 ASSERT_EQ(a1.size(), 0);
744 ASSERT_EQ(a1.capacity(), 0);
745 ASSERT_EQ(a1.data(), nullptr);
746
747 std::cout << "Array a2\n";
748 UniqueArray<Int32> a2(a1);
749 ASSERT_EQ(a1.allocator(), a2.allocator());
750 ASSERT_EQ(a2.capacity(), 0);
751 ASSERT_EQ(a2.data(), nullptr);
752 a1.reserve(3);
753 a1.add(5);
754 a1.add(7);
755 a1.add(12);
756 a1.add(3);
757 a1.add(1);
758 ASSERT_EQ(a1.size(), 5);
759
760 std::cout << "Array a3\n";
761 UniqueArray<Int32> a3(allocator1);
762 a3.add(4);
763 a3.add(6);
764 a3.add(2);
765 ASSERT_EQ(a3.size(), 3);
766 a3 = a1;
767 ASSERT_EQ(a3.allocator(), a1.allocator());
768 ASSERT_EQ(a3.size(), a1.size());
769 ASSERT_EQ(a3.constSpan(), a1.constSpan());
770
771 std::cout << "Array a4\n";
772 UniqueArray<Int32> a4(allocator1);
773 a4.add(4);
774 a4.add(6);
775 a4.add(2);
776 ASSERT_EQ(a4.size(), 3);
777 a4 = a1.span();
778 ASSERT_EQ(a4.allocator(), allocator1);
779
780 a4 = UniqueArray<Int32>(&printable_allocator2);
781
782 UniqueArray<Int32> array[2];
783 IMemoryAllocator* allocator3 = allocator1;
784 for( Integer i=0; i<2; ++i ){
785 array[i] = UniqueArray<Int32>(allocator3);
786 }
787 ASSERT_EQ(array[0].allocator(), allocator3);
788 ASSERT_EQ(array[1].allocator(), allocator3);
789 }
790}
791
792/*---------------------------------------------------------------------------*/
793/*---------------------------------------------------------------------------*/
794
796{
797 using namespace Arccore;
798 std::cout << "Sizeof(MemoryAllocationOptions)=" << sizeof(MemoryAllocationOptions) << "\n";
799 std::cout << "Sizeof(ArrayMetaData)=" << sizeof(ArrayMetaData) << "\n";
800 std::cout << "Sizeof(UniqueArray<Int32>)=" << sizeof(UniqueArray<Int32>) << "\n";
801 std::cout << "Sizeof(SharedArray<Int32>)=" << sizeof(SharedArray<Int32>) << "\n";
802
803 PrintableMemoryAllocator printable_allocator;
804 PrintableMemoryAllocator printable_allocator2;
807 {
808 std::cout << "Array a1\n";
809 SharedArray<Int32> a1(allocator2);
810 ASSERT_EQ(a1.allocator(), allocator2);
811 ASSERT_EQ(a1.size(), 0);
812 ASSERT_EQ(a1.capacity(), 0);
813 ASSERT_EQ(a1.data(), nullptr);
814
815 std::cout << "Array a2\n";
816 SharedArray<Int32> a2(a1);
817 ASSERT_EQ(a1.allocator(), a2.allocator());
818 ASSERT_EQ(a2.capacity(), 0);
819 ASSERT_EQ(a2.data(), nullptr);
820 a1.reserve(3);
821 a1.add(5);
822 a1.add(7);
823 a1.add(12);
824 a1.add(3);
825 a1.add(1);
826 ASSERT_EQ(a1.size(), 5);
827
828 std::cout << "Array a3\n";
829 SharedArray<Int32> a3(allocator1);
830 a3.add(4);
831 a3.add(6);
832 a3.add(2);
833 ASSERT_EQ(a3.size(), 3);
834 a3 = a1;
835 ASSERT_EQ(a3.allocator(), a1.allocator());
836 ASSERT_EQ(a3.size(), a1.size());
837 ASSERT_EQ(a3.constSpan(), a1.constSpan());
838
839 std::cout << "Array a4\n";
840 SharedArray<Int32> a4(allocator1);
841 a4.add(4);
842 a4.add(6);
843 a4.add(2);
844 ASSERT_EQ(a4.size(), 3);
845 a4 = a1.span();
846 ASSERT_EQ(a4.allocator(), allocator1);
847
848 a4 = SharedArray<Int32>(&printable_allocator2);
849
850 SharedArray<Int32> array[2];
851 IMemoryAllocator* allocator3 = allocator1;
852 for( Integer i=0; i<2; ++i ){
853 array[i] = SharedArray<Int32>(allocator3);
854 }
855 ASSERT_EQ(array[0].allocator(), allocator3);
856 ASSERT_EQ(array[1].allocator(), allocator3);
857 }
858}
859
868: public IMemoryAllocator3
869{
870 public:
871
872 bool hasRealloc(MemoryAllocationArgs args) const override
873 {
874 _checkValid(args);
875 return m_default_allocator.hasRealloc(args);
876 }
878 {
879 _checkValid(args);
880 return m_default_allocator.allocate(args,new_size);
881 }
883 {
884 _checkValid(args);
885 return m_default_allocator.reallocate(args, current_ptr, new_size);
886 }
888 {
889 _checkValid(args);
890 m_default_allocator.deallocate(args, ptr);
891 }
892 Int64 adjustedCapacity(MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const override
893 {
894 _checkValid(args);
895 return m_default_allocator.adjustedCapacity(args, wanted_capacity, element_size);
896 }
897 size_t guarantedAlignment(MemoryAllocationArgs args) const override
898 {
899 _checkValid(args);
900 return m_default_allocator.guaranteedAlignment(args);
901 }
902
904 {
905 // Cette méthode n'est appelée qu'une seule fois donc on teste directement les valeurs attendues
906 ASSERT_EQ(old_args.memoryLocationHint(), eMemoryLocationHint::None);
907 ASSERT_EQ(new_args.memoryLocationHint(), eMemoryLocationHint::MainlyHost);
908 ASSERT_EQ(ptr.size(), 8);
909 m_default_allocator.notifyMemoryArgsChanged(old_args, new_args, ptr);
910 }
911
912 private:
913
914 DefaultMemoryAllocator3 m_default_allocator;
915
916 private:
917
918 static void _checkValid(MemoryAllocationArgs args)
919 {
920 bool v1 = args.memoryLocationHint() == eMemoryLocationHint::None;
921 bool v2 = args.memoryLocationHint() == eMemoryLocationHint::MainlyHost;
922 bool v3 = args.memoryLocationHint() == eMemoryLocationHint::HostAndDeviceMostlyRead;
923 bool is_valid = v1 || v2 || v3;
924 ASSERT_TRUE(is_valid);
925 }
926};
927
928#define ASSERT_SAME_ARRAY_INFOS(a,b) \
929 ASSERT_EQ(a.allocationOptions(), b.allocationOptions());\
930 ASSERT_EQ(a.size(), b.size());\
931 ASSERT_EQ(a.capacity(), b.capacity())
932
933TEST(Array, AllocatorV2)
934{
935 using namespace Arccore;
936 TesterMemoryAllocatorV3 testerv2_allocator;
937 TesterMemoryAllocatorV3 testerv2_allocator2;
938 MemoryAllocationOptions allocate_options1(&testerv2_allocator, eMemoryLocationHint::HostAndDeviceMostlyRead);
939 MemoryAllocationOptions allocate_options2(&testerv2_allocator, eMemoryLocationHint::None, 0);
940 {
941 MemoryAllocationOptions opt3(&testerv2_allocator);
942 opt3.setMemoryLocationHint(eMemoryLocationHint::HostAndDeviceMostlyRead);
943 ASSERT_EQ(opt3, allocate_options1);
944 }
945 {
946 std::cout << "Array a1\n";
947 UniqueArray<Int32> a1(allocate_options2);
948 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
949 ASSERT_EQ(a1.size(), 0);
950 ASSERT_EQ(a1.capacity(), 0);
951 ASSERT_EQ(a1.data(), nullptr);
952
953 std::cout << "Array a2\n";
954 UniqueArray<Int32> a2(a1);
955 ASSERT_SAME_ARRAY_INFOS(a2, a1);
956 ASSERT_EQ(a2.data(), nullptr);
957 a1.reserve(3);
958 a1.add(5);
959 a1.add(7);
960 a1.add(12);
961 a1.add(3);
962 a1.add(1);
963 ASSERT_EQ(a1.size(), 5);
964 a2.add(9);
965 a2.add(17);
966 // Pour tester notifyMemoryArgsChanged()
967 a2.setMemoryLocationHint(eMemoryLocationHint::MainlyHost);
968
969 std::cout << "Array a3\n";
970 UniqueArray<Int32> a3(allocate_options1);
971 a3.add(4);
972 a3.add(6);
973 a3.add(2);
974 ASSERT_EQ(a3.size(), 3);
975 a3 = a1;
976 ASSERT_EQ(a3.allocator(), a1.allocator());
977 ASSERT_EQ(a3.size(), a1.size());
978 ASSERT_EQ(a3.constSpan(), a1.constSpan());
979
980 std::cout << "Array a4\n";
981 UniqueArray<Int32> a4(allocate_options1);
982 a4.add(4);
983 a4.add(6);
984 a4.add(2);
985 ASSERT_EQ(a4.size(), 3);
986 a4 = a1.span();
987 ASSERT_EQ(a4.allocationOptions(), allocate_options1);
988
989 a4 = UniqueArray<Int32>(&testerv2_allocator2);
990
991 UniqueArray<Int32> array[2];
992 MemoryAllocationOptions allocator3 = allocate_options1;
993 for (Integer i = 0; i < 2; ++i) {
994 array[i] = UniqueArray<Int32>(allocator3);
995 }
996 ASSERT_EQ(array[0].allocationOptions(), allocator3);
997 ASSERT_EQ(array[1].allocationOptions(), allocator3);
998 }
999}
1000
1001/*---------------------------------------------------------------------------*/
1002/*---------------------------------------------------------------------------*/
1003
1004TEST(Array, DebugInfo)
1005{
1006 using namespace Arccore;
1007 DefaultMemoryAllocator3 m_default_allocator;
1008 MemoryAllocationOptions allocate_options2(&m_default_allocator, eMemoryLocationHint::None, 0);
1009
1010 String a1_name("Array1");
1012 {
1013 std::cout << "Array a1\n";
1014 UniqueArray<Int32> a1(allocate_options2);
1015 a1.setDebugName(a1_name);
1016 ASSERT_EQ(a1.allocationOptions(), allocate_options2);
1017 ASSERT_EQ(a1.size(), 0);
1018 ASSERT_EQ(a1.capacity(), 0);
1019 ASSERT_EQ(a1.data(), nullptr);
1020 ASSERT_EQ(a1.debugName(), a1_name);
1021
1022 std::cout << "Array a2\n";
1023 UniqueArray<Int32> a2(a1);
1024 ASSERT_SAME_ARRAY_INFOS(a2, a1);
1025 ASSERT_EQ(a2.data(), nullptr);
1026 ASSERT_EQ(a2.debugName(), a1_name);
1027 a1.reserve(3);
1028 a1.add(5);
1029 a1.add(7);
1030 a1.add(12);
1031 a1.add(3);
1032 a1.add(1);
1033 ASSERT_EQ(a1.size(), 5);
1034 a2.add(9);
1035 a2.add(17);
1036 ASSERT_EQ(a2.debugName(), a1_name);
1037 ASSERT_EQ(a2.size(), 2);
1038
1039 a3 = a2;
1040 }
1041 ASSERT_EQ(a3.debugName(), a1_name);
1042 ASSERT_EQ(a3.size(), 2);
1043}
1044
1045/*---------------------------------------------------------------------------*/
1046/*---------------------------------------------------------------------------*/
1047
1048TEST(Collections, Memory)
1049{
1050 using namespace Arccore;
1051 std::cout << eHostDeviceMemoryLocation::Unknown << " "
1052 << eHostDeviceMemoryLocation::Device << " "
1053 << eHostDeviceMemoryLocation::Host << " "
1054 << eHostDeviceMemoryLocation::ManagedMemoryDevice << " "
1055 << eHostDeviceMemoryLocation::ManagedMemoryHost << "\n";
1056
1057 std::cout << eMemoryResource::Unknown << " "
1058 << eMemoryResource::Host << " "
1059 << eMemoryResource::HostPinned << " "
1060 << eMemoryResource::Device << " "
1061 << eMemoryResource::UnifiedMemory << "\n";
1062
1064 ASSERT_EQ(a1.hostDeviceMemoryLocation(), eHostDeviceMemoryLocation::Unknown);
1065 a1._internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation::Host);
1066 ASSERT_EQ(a1.hostDeviceMemoryLocation(), eHostDeviceMemoryLocation::Host);
1067}
1068
1069/*---------------------------------------------------------------------------*/
1070/*---------------------------------------------------------------------------*/
1071
1072namespace Arccore
1073{
1074// Instancie explicitement les classes tableaux pour garantir
1075// que toutes les méthodes fonctionnent
1076template class UniqueArray<IntSubClass>;
1077template class SharedArray<IntSubClass>;
1078template class Array<IntSubClass>;
1079template class AbstractArray<IntSubClass>;
1080} // namespace Arccore
#define ASSERT_TRUE(condition)
Vérifie que condition est vrai.
Definition Assertion.h:126
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:149
String debugName() const
Nom de debug (nul si aucun nom spécifié)
void _internalSetHostDeviceMemoryLocation(eHostDeviceMemoryLocation location)
Positionne l'emplacement physique de la zone mémoire.
eHostDeviceMemoryLocation hostDeviceMemoryLocation() const
Positionne l'emplacement physique de la zone mémoire.
Integer size() const
Nombre d'éléments du vecteur.
static constexpr Integer simdAlignment()
Alignement pour les structures utilisant la vectorisation.
static AlignedMemoryAllocator3 * Simd()
Allocateur garantissant l'alignement pour utiliser la vectorisation sur la plateforme cible.
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.
Classe de base des vecteurs 1D de données.
Span< const T > span() const
Vue immutable sur ce tableau.
iterator begin()
Itérateur sur le premier élément du tableau.
void copy(Span< const T > rhs)
Copie les valeurs de rhs dans l'instance.
reverse_iterator rbegin()
Itérateur inverse sur le premier élément du tableau.
void resizeNoInit(Int64 s)
Redimensionne sans initialiser les nouvelles valeurs.
void reserve(Int64 new_capacity)
Réserve le mémoire pour new_capacity éléments.
SmallSpan< const T > smallSpan() const
Vue immutable sur ce tableau.
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 remove(Int64 index)
Supprime l'entité ayant l'indice index.
ConstArrayView< T > constView() const
Vue constante sur ce tableau.
ArrayView< T > view() const
Vue mutable sur ce tableau.
SmallSpan< const T > constSmallSpan() const
Vue immutable sur ce tableau.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Span< const T > constSpan() const
Vue constante sur ce tableau.
reverse_iterator rend()
Itérateur inverse sur le premier élément après la fin du tableau.
ConstArrayView< T > subConstView(Int64 abegin, Int32 asize) const
Sous-vue à partir de l'élément abegin et contenant asize éléments.
iterator end()
Itérateur sur le premier élément après la fin du tableau.
interval d'itérateurs constant
bool hasRealloc(MemoryAllocationArgs) const override
Indique si l'allocateur supporte la sémantique de realloc.
AllocatedMemoryInfo reallocate(MemoryAllocationArgs, AllocatedMemoryInfo current_ptr, Int64 new_size) override
Réalloue de la mémoire pour new_size octets et retourne le pointeur.
Int64 adjustedCapacity(MemoryAllocationArgs, Int64 wanted_capacity, Int64 element_size) const override
Ajuste la capacité suivant la taille d'élément.
void deallocate(MemoryAllocationArgs, AllocatedMemoryInfo ptr) override
Libère la mémoire dont l'adresse de base est ptr.
AllocatedMemoryInfo allocate(MemoryAllocationArgs, Int64 new_size) override
Alloue de la mémoire pour new_size octets et retourne le pointeur.
Classe de base d'une exception.
virtual size_t guaranteedAlignment(MemoryAllocationArgs args) const
Valeur de l'alignement garanti par l'allocateur.
virtual void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr)
Notifie du changement des arguments spécifiques à l'instance.
Classe contenant des informations pour spécialiser les allocations.
Options pour configurer 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:670
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:869
void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr) override
Notifie du changement des arguments spécifiques à l'instance.
Definition TestArray.cc:903
AllocatedMemoryInfo reallocate(MemoryAllocationArgs args, AllocatedMemoryInfo current_ptr, Int64 new_size) override
Réalloue de la mémoire pour new_size octets et retourne le pointeur.
Definition TestArray.cc:882
size_t guarantedAlignment(MemoryAllocationArgs args) const override
Valeur de l'alignement garanti par l'allocateur.
Definition TestArray.cc:897
void deallocate(MemoryAllocationArgs args, AllocatedMemoryInfo ptr) override
Libère la mémoire dont l'adresse de base est ptr.
Definition TestArray.cc:887
AllocatedMemoryInfo allocate(MemoryAllocationArgs args, Int64 new_size) override
Alloue de la mémoire pour new_size octets et retourne le pointeur.
Definition TestArray.cc:877
Int64 adjustedCapacity(MemoryAllocationArgs args, Int64 wanted_capacity, Int64 element_size) const override
Ajuste la capacité suivant la taille d'élément.
Definition TestArray.cc:892
bool hasRealloc(MemoryAllocationArgs args) const override
Indique si l'allocateur supporte la sémantique de realloc.
Definition TestArray.cc:872
Concept for allocating, resizing and freeing memory block.
Espace de nom de Arccore.
Definition ArcaneTypes.h:24
void swap(UniqueArray< T > &v1, UniqueArray< T > &v2)
Échange les valeurs de v1 et v2.
double Real
Type représentant un réel.
Int32 Integer
Type représentant un entier.
std::int64_t Int64
Type entier signé sur 64 bits.