9.1
general documentation
cs_array_2dspan.h
Go to the documentation of this file.
1#ifndef __CS_ARRAY_2DSPAN_H__
2#define __CS_ARRAY_2DSPAN_H__
3
4/*============================================================================
5 * Templated 2D array object
6 *============================================================================*/
7
8/*
9 This file is part of code_saturne, a general-purpose CFD tool.
10
11 Copyright (C) 1998-2025 EDF S.A.
12
13 This program is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free Software
15 Foundation; either version 2 of the License, or (at your option) any later
16 version.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21 details.
22
23 You should have received a copy of the GNU General Public License along with
24 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25 Street, Fifth Floor, Boston, MA 02110-1301, USA.
26*/
27
28/*----------------------------------------------------------------------------*/
29
30/*----------------------------------------------------------------------------
31 * Local headers
32 *----------------------------------------------------------------------------*/
33
34#include "bft/bft_error.h"
35
36#include "base/cs_defs.h"
37
38#include "base/cs_array.h"
39#include "base/cs_mem.h"
40
41#if defined(__cplusplus)
42
43/*=============================================================================
44 * BUILTIN TEST
45 *============================================================================*/
46
47#ifndef __has_builtin
48#define __has_builtin(x) 0
49#endif
50
51/*=============================================================================
52 * Public C++ class template
53 *============================================================================*/
54
55namespace cs {
56
57/*----------------------------------------------------------------------------*/
61/*----------------------------------------------------------------------------*/
62
63template <class T>
65public:
66
67 /*--------------------------------------------------------------------------*/
71 /*--------------------------------------------------------------------------*/
72
75 _dim1(0),
76 _dim2(0),
77 _size(0),
78 _is_owner(true),
79 _full_array(nullptr),
80 _mode(cs_alloc_mode)
81 {
82 }
83
84 /*--------------------------------------------------------------------------*/
88 /*--------------------------------------------------------------------------*/
89
92 (
95#if (defined(__GNUC__) || defined(__clang__)) && \
96 __has_builtin(__builtin_LINE) && \
97 __has_builtin(__builtin_FILE)
98 const char *file_name = __builtin_FILE(),
99 const int line_number = __builtin_LINE()
100#else
101 const char *file_name = __FILE__,
102 const int line_number = __LINE__
103#endif
104 )
105 :
106 _dim1(dim1),
107 _dim2(dim2),
108 _size(dim1*dim2),
109 _is_owner(true),
110 _mode(cs_alloc_mode)
111 {
112 allocate_(file_name, line_number);
113 }
114
115 /*--------------------------------------------------------------------------*/
119 /*--------------------------------------------------------------------------*/
120
123 (
126 cs_alloc_mode_t alloc_mode,
127#if (defined(__GNUC__) || defined(__clang__)) && \
128 __has_builtin(__builtin_LINE) && \
129 __has_builtin(__builtin_FILE)
130 const char *file_name = __builtin_FILE(),
131 const int line_number = __builtin_LINE()
132#else
133 const char *file_name = __FILE__,
134 const int line_number = __LINE__
135#endif
136 )
137 :
138 _dim1(dim1),
139 _dim2(dim2),
140 _size(dim1 * dim2),
141 _is_owner(true),
142 _mode(alloc_mode)
143 {
144 allocate_(file_name, line_number);
145 }
146
147 /*--------------------------------------------------------------------------*/
151 /*--------------------------------------------------------------------------*/
152
155 (
158 T* data_array,
159 cs_alloc_mode_t alloc_mode = cs_alloc_mode
161 )
162 :
163 _dim1(dim1),
164 _dim2(dim2),
165 _size(dim1 * dim2),
166 _is_owner(false),
167 _mode(alloc_mode),
168 _full_array(data_array)
169 {
170 }
171
172 /*--------------------------------------------------------------------------*/
176 /*--------------------------------------------------------------------------*/
177
180 (
181 array_2dspan& other,
182 bool shallow_copy=false,
183#if (defined(__GNUC__) || defined(__clang__)) && \
184 __has_builtin(__builtin_LINE) && \
185 __has_builtin(__builtin_FILE)
186 const char *file_name = __builtin_FILE(),
187 const int line_number = __builtin_LINE()
188#else
189 const char *file_name = __FILE__,
190 const int line_number = __LINE__
191#endif
192 )
193 {
194 set_size_(other._dim1, other._dim2);
195 _mode = other._mode;
196
197 /* If shallow copy new instance is not owner. Otherwise same ownership
198 * as original instance since we copy it.
199 */
200 _is_owner = (shallow_copy) ? false : other._is_owner;
201
202 if (_is_owner) {
203 allocate_(file_name, line_number);
204 cs_array_copy<T>(_size, other._full_array, _full_array);
205 }
206 else {
207 _full_array = other._full_array;
208 }
209 }
210
211 /*--------------------------------------------------------------------------*/
215 /*--------------------------------------------------------------------------*/
216
219 (
220 array_2dspan&& other
221 )
222 : array_2dspan()
223 {
224 swap(*this, other);
225 }
226
227 /*--------------------------------------------------------------------------*/
231 /*--------------------------------------------------------------------------*/
232
235 {
236 clear();
237 }
238
239 /*--------------------------------------------------------------------------*/
243 /*--------------------------------------------------------------------------*/
244
246 friend void
248 (
249 array_2dspan& first,
250 array_2dspan& second
251 )
252 {
253 using std::swap;
254 /* Swap the different members between the two references. */
255 swap(first._dim1, second._dim1);
256 swap(first._dim2, second._dim2);
257 swap(first._size, second._size);
258 swap(first._is_owner, second._is_owner);
259 swap(first._mode, second._mode);
260 swap(first._full_array, second._full_array);
261 }
262
263 /*--------------------------------------------------------------------------*/
267 /*--------------------------------------------------------------------------*/
268
271 {
272 swap(*this, other);
273
274 return *this;
275 }
276
277 /*--------------------------------------------------------------------------*/
281 /*--------------------------------------------------------------------------*/
282
284 void
286 {
287 if (_is_owner) {
288 CS_FREE(_full_array);
289 }
290 else {
291 _full_array = nullptr;
292 }
293
294 set_size_(0,0);
295 }
296
297 /*--------------------------------------------------------------------------*/
301 /*--------------------------------------------------------------------------*/
302
304 void
306 {
307 set_size_(0, 0);
308 _is_owner = false;
309 _full_array = nullptr;
310 _mode = cs_alloc_mode;
311 }
312
313 /*--------------------------------------------------------------------------*/
317 /*--------------------------------------------------------------------------*/
318
320 void
322 (
323 array_2dspan& other
325 )
326 {
327 clear();
328 *this = other.view();
329 }
330
331 /*--------------------------------------------------------------------------*/
335 /*--------------------------------------------------------------------------*/
336
339 (
340 T val
341 )
342 {
343 cs_arrays_set_value<T,1>(_size, val, _full_array);
344 }
345
346 /*--------------------------------------------------------------------------*/
350 /*--------------------------------------------------------------------------*/
351
354 (
357#if (defined(__GNUC__) || defined(__clang__)) && \
358 __has_builtin(__builtin_LINE) && \
359 __has_builtin(__builtin_FILE)
360 const char *file_name = __builtin_FILE(),
361 const int line_number = __builtin_LINE()
362#else
363 const char *file_name = __FILE__,
364 const int line_number = __LINE__
365#endif
366 )
367 {
368 assert(dim1 >= 0 && dim2 >= 0);
369
370 /* If same dimensions, nothing to do ... */
371 if (dim1 == _dim1 && dim2 == _dim2)
372 return;
373
374 if (_is_owner) {
375 clear();
376 set_size_(dim1, dim2);
377 allocate_(file_name, line_number);
378 }
379
380 }
381
382 /*--------------------------------------------------------------------------*/
386 /*--------------------------------------------------------------------------*/
387
390 (
393 bool copy_data,
395 cs_lnum_t size_to_keep,
396#if (defined(__GNUC__) || defined(__clang__)) && \
397 __has_builtin(__builtin_LINE) && \
398 __has_builtin(__builtin_FILE)
399 const char *file_name = __builtin_FILE(),
400 const int line_number = __builtin_LINE()
401#else
402 const char *file_name = __FILE__,
403 const int line_number = __LINE__
404#endif
405 )
406 {
407 assert(dim1 >= 0 && dim2 >= 0);
408 assert(size_to_keep <= dim2 && size_to_keep <= _dim2);
409
410 /* If same dimensions, nothing to do ... */
411 if (dim1 == _dim1 && dim2 == _dim2)
412 return;
413
414 if (copy_data && dim1 < _dim1)
415 bft_error(__FILE__, __LINE__, 0,
416 "%s: Data cannot be saved when new dim1 is smaller than previous.\n",
417 __func__);
418
419 if (_is_owner) {
420 if (copy_data) {
421 /* If we change dim1 -> Realloc is sufficient */
422 if (_dim1 != dim1) {
423 set_size_(dim1, dim2);
424 reallocate_(file_name, line_number);
425 }
426 else {
427 /* Temporary copy */
428 T *tmp = nullptr;
429 CS_MALLOC_HD(tmp, _size, T, _mode);
430
431 cs_array_copy<T>(_size, _full_array, tmp);
432
433 cs_lnum_t old_dim2 = _dim2;
434
435 resize(dim1, dim2, file_name, line_number);
436
437 /* We loop on "_dim1" since dim1 = _dim1 */
438 for (cs_lnum_t i = 0; i < _dim1; i++) {
439 cs_array_copy<T>(size_to_keep,
440 tmp + i*old_dim2,
441 _full_array + i*_dim2);
442 }
443
444 CS_FREE(tmp);
445 }
446 }
447 else {
448 resize(dim1, dim2, file_name, line_number);
449 }
450 }
451
452 }
453
454 /*--------------------------------------------------------------------------*/
460 /*--------------------------------------------------------------------------*/
461
464 {
465 /* Use the shallow copy constructor to return a temporary instance */
466 return array_2dspan(*this, true);
467 }
468
469 /*--------------------------------------------------------------------------*/
473 /*--------------------------------------------------------------------------*/
474
477 (
478 cs_alloc_mode_t mode
479 )
480 {
481 if (_mode != mode) {
482 if (_size != 0)
483 clear();
484
485 _mode = mode;
486 }
487 }
488
489 /*--------------------------------------------------------------------------*/
495 /*--------------------------------------------------------------------------*/
496
498 T *vals()
499 {
500 return _full_array;
501 }
502
503 /*--------------------------------------------------------------------------*/
509 /*--------------------------------------------------------------------------*/
510
512 const T *vals() const
513 {
514 return _full_array;
515 }
516
517 /*--------------------------------------------------------------------------*/
523 /*--------------------------------------------------------------------------*/
524
526 T* operator[]
527 (
528 int i
529 )
530 {
531 return _full_array + i * _dim2;
532 }
533
534 /*--------------------------------------------------------------------------*/
540 /*--------------------------------------------------------------------------*/
541
543 const T* operator[]
544 (
545 int i
546 ) const
547 {
548 return _full_array + i * _dim2;
549 }
550
551 /*--------------------------------------------------------------------------*/
557 /*--------------------------------------------------------------------------*/
558
561 {
562 return _dim1;
563 }
564
565 /*--------------------------------------------------------------------------*/
571 /*--------------------------------------------------------------------------*/
572
575 {
576 return _dim2;
577 }
578
579 /*--------------------------------------------------------------------------*/
585 /*--------------------------------------------------------------------------*/
586
589 {
590 return _size;
591 }
592
593private:
594
595 /*--------------------------------------------------------------------------*/
599 /*--------------------------------------------------------------------------*/
600
602 void
603 set_size_
604 (
607 )
608 {
609 _dim1 = dim1;
610 _dim2 = dim2;
611 _size = dim1 * dim2;
612 }
613
614 /*--------------------------------------------------------------------------*/
618 /*--------------------------------------------------------------------------*/
619
621 void
622 allocate_
623 (
624 const char *file_name,
625 const int line_number
626 )
627 {
628 const char *_ptr_name = "_full_array";
629 _full_array = static_cast<T *>(cs_mem_malloc_hd(_mode,
630 _size,
631 sizeof(T),
632 _ptr_name,
633 file_name,
634 line_number));
635 }
636
637 /*--------------------------------------------------------------------------*/
641 /*--------------------------------------------------------------------------*/
642
644 void
645 reallocate_
646 (
647 const char *file_name,
648 const int line_number
649 )
650 {
651 /* If not owner no-op */
652 if (_is_owner) {
653 const char *_ptr_name = "_full_array";
654 _full_array = static_cast<T *>(cs_mem_realloc_hd(_full_array,
655 _mode,
656 _size,
657 sizeof(T),
658 _ptr_name,
659 file_name,
660 line_number));
661 }
662 };
663
664 /*--------------------------------------------------------------------------*/
665 /* Private members */
666 /*--------------------------------------------------------------------------*/
667
668 cs_lnum_t _dim1;
669 cs_lnum_t _dim2;
670 cs_lnum_t _size;
671 bool _is_owner;
672 T* _full_array;
673 cs_alloc_mode_t _mode;
674};
675
676}
677
678/*----------------------------------------------------------------------------*/
679
680#endif // __cplusplus
681
682/*----------------------------------------------------------------------------*/
683
684#endif // __CS_ARRAY_2DSPAN_H__
void bft_error(const char *const file_name, const int line_num, const int sys_error_code, const char *const format,...)
Calls the error handler (set by bft_error_handler_set() or default).
Definition: bft_error.cpp:193
Definition: cs_array_2dspan.h:64
CS_F_HOST_DEVICE void set_alloc_mode(cs_alloc_mode_t mode)
Set memory allocation mode.
Definition: cs_array_2dspan.h:477
CS_F_HOST_DEVICE T * vals()
Getter function for full array.
Definition: cs_array_2dspan.h:498
CS_F_HOST_DEVICE const T * vals() const
Const getter function for full array.
Definition: cs_array_2dspan.h:512
CS_F_HOST_DEVICE cs_lnum_t size()
Getter function for total size.
Definition: cs_array_2dspan.h:588
CS_F_HOST_DEVICE cs_lnum_t dim2()
Getter function for second dimension size.
Definition: cs_array_2dspan.h:574
CS_F_HOST_DEVICE ~array_2dspan()
Destructor method.
Definition: cs_array_2dspan.h:234
CS_F_HOST_DEVICE array_2dspan(array_2dspan &other, bool shallow_copy=false, const char *file_name=__FILE__, const int line_number=__LINE__)
Constructor method using copy. May be a shallow copy.
Definition: cs_array_2dspan.h:180
CS_F_HOST_DEVICE array_2dspan(cs_lnum_t dim1, cs_lnum_t dim2, cs_alloc_mode_t alloc_mode, const char *file_name=__FILE__, const int line_number=__LINE__)
Constructor method with specified allocation method.
Definition: cs_array_2dspan.h:123
CS_F_HOST_DEVICE friend void swap(array_2dspan &first, array_2dspan &second)
Class swap operator used for assignment or move.
Definition: cs_array_2dspan.h:248
CS_F_HOST_DEVICE void resize(cs_lnum_t dim1, cs_lnum_t dim2, const char *file_name=__FILE__, const int line_number=__LINE__)
Resize data array.
Definition: cs_array_2dspan.h:354
CS_F_HOST_DEVICE void resize(cs_lnum_t dim1, cs_lnum_t dim2, bool copy_data, cs_lnum_t size_to_keep, const char *file_name=__FILE__, const int line_number=__LINE__)
Resize data array while keeping some of the old data.
Definition: cs_array_2dspan.h:390
CS_F_HOST_DEVICE array_2dspan()
Default constructor method leading to "empty container".
Definition: cs_array_2dspan.h:74
CS_F_HOST_DEVICE array_2dspan view()
Get a view (non owner) of the array.
Definition: cs_array_2dspan.h:463
CS_F_HOST_DEVICE void empty()
Initializer method for empty containers.
Definition: cs_array_2dspan.h:305
CS_F_HOST_DEVICE array_2dspan(cs_lnum_t dim1, cs_lnum_t dim2, const char *file_name=__FILE__, const int line_number=__LINE__)
Constructor method using only dimension.
Definition: cs_array_2dspan.h:92
CS_F_HOST_DEVICE void clear()
Clear data (empty container).
Definition: cs_array_2dspan.h:285
CS_F_HOST_DEVICE array_2dspan(array_2dspan &&other)
Move constructor.
Definition: cs_array_2dspan.h:219
CS_F_HOST_DEVICE array_2dspan(cs_lnum_t dim1, cs_lnum_t dim2, T *data_array, cs_alloc_mode_t alloc_mode=cs_alloc_mode)
Constructor method for non owner version.
Definition: cs_array_2dspan.h:155
CS_F_HOST_DEVICE cs_lnum_t dim1()
Getter function for first dimension size.
Definition: cs_array_2dspan.h:560
CS_F_HOST_DEVICE void point_to(array_2dspan &other)
Change pointers/size of an existing container.
Definition: cs_array_2dspan.h:322
CS_F_HOST_DEVICE array_2dspan & operator=(array_2dspan other)
Assignment operator.
Definition: cs_array_2dspan.h:270
CS_F_HOST_DEVICE void set_to_val(T val)
Set all values of the data array to a constant value.
Definition: cs_array_2dspan.h:339
#define __has_builtin(x)
Definition: cs_array_2dspan.h:48
#define CS_F_HOST_DEVICE
Definition: cs_defs.h:585
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:350
#define CS_FREE(_ptr)
Definition: cs_mem.h:155
#define CS_MALLOC_HD(_ptr, _ni, _type, _mode)
Definition: cs_mem.h:99
#define cs_alloc_mode
Definition: cs_mem.h:187
cs_alloc_mode_t
Definition: cs_mem.h:50
Definition: cs_array.h:1098