9.0
general documentation
Loading...
Searching...
No Matches
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>
64class array_2dspan {
65public:
66
67 /*--------------------------------------------------------------------------*/
71 /*--------------------------------------------------------------------------*/
72
74 array_2dspan() :
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
91 array_2dspan
92 (
93 cs_lnum_t dim1,
94 cs_lnum_t dim2,
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
122 array_2dspan
123 (
124 cs_lnum_t dim1,
125 cs_lnum_t dim2,
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
154 array_2dspan
155 (
156 cs_lnum_t dim1,
157 cs_lnum_t dim2,
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
179 array_2dspan
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
218 array_2dspan
219 (
220 array_2dspan&& other
221 )
222 : array_2dspan()
223 {
224 swap(*this, other);
225 }
226 /*--------------------------------------------------------------------------*/
230 /*--------------------------------------------------------------------------*/
231
233 ~array_2dspan()
234 {
235 clear();
236 }
237
238 /*--------------------------------------------------------------------------*/
242 /*--------------------------------------------------------------------------*/
243
245 friend void
246 swap
247 (
248 array_2dspan& first,
249 array_2dspan& second
250 )
251 {
252 using std::swap;
253 /* Swap the different members between the two references. */
254 swap(first._dim1, second._dim1);
255 swap(first._dim2, second._dim2);
256 swap(first._size, second._size);
257 swap(first._is_owner, second._is_owner);
258 swap(first._mode, second._mode);
259 swap(first._full_array, second._full_array);
260 }
261
262 /*--------------------------------------------------------------------------*/
266 /*--------------------------------------------------------------------------*/
267
269 array_2dspan& operator=(array_2dspan other)
270 {
271 swap(*this, other);
272
273 return *this;
274 }
275
276 /*--------------------------------------------------------------------------*/
280 /*--------------------------------------------------------------------------*/
281
283 void
284 clear()
285 {
286 if (_is_owner) {
287 CS_FREE(_full_array);
288 }
289 else {
290 _full_array = nullptr;
291 }
292
293 set_size_(0,0);
294 }
295
296 /*--------------------------------------------------------------------------*/
300 /*--------------------------------------------------------------------------*/
301
303 void
304 empty()
305 {
306 set_size_(0, 0);
307 _is_owner = false;
308 _full_array = nullptr;
309 _mode = cs_alloc_mode;
310 }
311
312 /*--------------------------------------------------------------------------*/
316 /*--------------------------------------------------------------------------*/
317
319 void
320 point_to
321 (
322 array_2dspan& other
324 )
325 {
326 clear();
327 *this = other.view();
328 }
329
330 /*--------------------------------------------------------------------------*/
334 /*--------------------------------------------------------------------------*/
335
337 void set_to_val
338 (
339 T val
340 )
341 {
342 cs_arrays_set_value<T,1>(_size, val, _full_array);
343 }
344
345 /*--------------------------------------------------------------------------*/
349 /*--------------------------------------------------------------------------*/
350
352 void resize
353 (
354 cs_lnum_t dim1,
355 cs_lnum_t dim2,
356#if (defined(__GNUC__) || defined(__clang__)) && \
357 __has_builtin(__builtin_LINE) && \
358 __has_builtin(__builtin_FILE)
359 const char *file_name = __builtin_FILE(),
360 const int line_number = __builtin_LINE()
361#else
362 const char *file_name = __FILE__,
363 const int line_number = __LINE__
364#endif
365 )
366 {
367 assert(dim1 >= 0 && dim2 >= 0);
368
369 /* If same dimensions, nothing to do ... */
370 if (dim1 == _dim1 && dim2 == _dim2)
371 return;
372
373 if (_is_owner) {
374 clear();
375 set_size_(dim1, dim2);
376 allocate_(file_name, line_number);
377 }
378
379 }
380
381 /*--------------------------------------------------------------------------*/
385 /*--------------------------------------------------------------------------*/
386
388 void resize
389 (
390 cs_lnum_t dim1,
391 cs_lnum_t dim2,
392 bool copy_data,
394 cs_lnum_t size_to_keep,
395#if (defined(__GNUC__) || defined(__clang__)) && \
396 __has_builtin(__builtin_LINE) && \
397 __has_builtin(__builtin_FILE)
398 const char *file_name = __builtin_FILE(),
399 const int line_number = __builtin_LINE()
400#else
401 const char *file_name = __FILE__,
402 const int line_number = __LINE__
403#endif
404 )
405 {
406 assert(dim1 >= 0 && dim2 >= 0);
407 assert(size_to_keep <= dim2 && size_to_keep <= _dim2);
408
409 /* If same dimensions, nothing to do ... */
410 if (dim1 == _dim1 && dim2 == _dim2)
411 return;
412
413 if (copy_data && dim1 < _dim1)
414 bft_error(__FILE__, __LINE__, 0,
415 "%s: Data cannot be saved when new dim1 is smaller than previous.\n",
416 __func__);
417
418 if (_is_owner) {
419 if (copy_data) {
420 /* If we change dim1 -> Realloc is sufficient */
421 if (_dim1 != dim1) {
422 set_size_(dim1, dim2);
423 reallocate_(file_name, line_number);
424 }
425 else {
426 /* Temporary copy */
427 T *tmp = nullptr;
428 CS_MALLOC_HD(tmp, _size, T, _mode);
429
430 cs_array_copy<T>(_size, _full_array, tmp);
431
432 cs_lnum_t old_dim2 = _dim2;
433
434 resize(dim1, dim2, file_name, line_number);
435
436 /* We loop on "_dim1" since dim1 = _dim1 */
437 for (cs_lnum_t i = 0; i < _dim1; i++) {
438 cs_array_copy<T>(size_to_keep,
439 tmp + i*old_dim2,
440 _full_array + i*_dim2);
441 }
442
443 CS_FREE(tmp);
444 }
445 }
446 else {
447 resize(dim1, dim2, file_name, line_number);
448 }
449 }
450
451 }
452
453 /*--------------------------------------------------------------------------*/
459 /*--------------------------------------------------------------------------*/
460
462 array_2dspan view()
463 {
464 /* Use the shallow copy constructor to return a temporary instance */
465 return array_2dspan(*this, true);
466 }
467
468 /*--------------------------------------------------------------------------*/
472 /*--------------------------------------------------------------------------*/
473
475 void set_alloc_mode
476 (
477 cs_alloc_mode_t mode
478 )
479 {
480 if (_mode != mode) {
481 if (_size != 0)
482 clear();
483
484 _mode = mode;
485 }
486 }
487
488 /*--------------------------------------------------------------------------*/
494 /*--------------------------------------------------------------------------*/
495
497 T *vals()
498 {
499 return _full_array;
500 }
501
502 /*--------------------------------------------------------------------------*/
508 /*--------------------------------------------------------------------------*/
509
511 const T *vals() const
512 {
513 return _full_array;
514 }
515
516 /*--------------------------------------------------------------------------*/
522 /*--------------------------------------------------------------------------*/
523
525 T* operator[]
526 (
527 int i
528 )
529 {
530 return _full_array + i * _dim2;
531 }
532
533 /*--------------------------------------------------------------------------*/
539 /*--------------------------------------------------------------------------*/
540
542 const T* operator[]
543 (
544 int i
545 ) const
546 {
547 return _full_array + i * _dim2;
548 }
549
550 /*--------------------------------------------------------------------------*/
556 /*--------------------------------------------------------------------------*/
557
559 cs_lnum_t dim1()
560 {
561 return _dim1;
562 }
563
564 /*--------------------------------------------------------------------------*/
570 /*--------------------------------------------------------------------------*/
571
573 cs_lnum_t dim2()
574 {
575 return _dim2;
576 }
577
578 /*--------------------------------------------------------------------------*/
584 /*--------------------------------------------------------------------------*/
585
587 cs_lnum_t size()
588 {
589 return _size;
590 }
591
592private:
593
594 /*--------------------------------------------------------------------------*/
598 /*--------------------------------------------------------------------------*/
599
601 void
602 set_size_
603 (
604 cs_lnum_t dim1,
605 cs_lnum_t dim2
606 )
607 {
608 _dim1 = dim1;
609 _dim2 = dim2;
610 _size = dim1 * dim2;
611 }
612
613 /*--------------------------------------------------------------------------*/
617 /*--------------------------------------------------------------------------*/
618
620 void
621 allocate_
622 (
623 const char *file_name,
624 const int line_number
625 )
626 {
627 const char *_ptr_name = "_full_array";
628 _full_array = static_cast<T *>(cs_mem_malloc_hd(_mode,
629 _size,
630 sizeof(T),
631 _ptr_name,
632 file_name,
633 line_number));
634 }
635
636 /*--------------------------------------------------------------------------*/
640 /*--------------------------------------------------------------------------*/
641
643 void
644 reallocate_
645 (
646 const char *file_name,
647 const int line_number
648 )
649 {
650 /* If not owner no-op */
651 if (_is_owner) {
652 const char *_ptr_name = "_full_array";
653 _full_array = static_cast<T *>(cs_mem_realloc_hd(_full_array,
654 _mode,
655 _size,
656 sizeof(T),
657 _ptr_name,
658 file_name,
659 line_number));
660 }
661 };
662
663 /*--------------------------------------------------------------------------*/
664 /* Private members */
665 /*--------------------------------------------------------------------------*/
666
667 cs_lnum_t _dim1;
668 cs_lnum_t _dim2;
669 cs_lnum_t _size;
670 bool _is_owner;
671 T* _full_array;
672 cs_alloc_mode_t _mode;
673};
674
675}
676
677/*----------------------------------------------------------------------------*/
678
679#endif // __cplusplus
680
681/*----------------------------------------------------------------------------*/
682
683#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
void cs_array_copy(cudaStream_t stream, const cs_lnum_t size, const T *src, T *dest)
Copy values from an array to another of the same dimensions.
Definition cs_array_cuda.h:212
void cs_arrays_set_value(cudaStream_t stream, const cs_lnum_t n_elts, const T *ref_val, Arrays &&... arrays)
Assign values to all elements of multiple arrays. ref_val is input as a pointer or an array.
Definition cs_array_cuda.h:120
#define CS_F_HOST_DEVICE
Definition cs_defs.h:561
#define true
Definition cs_defs.h:220
#define false
Definition cs_defs.h:219
int cs_lnum_t
local mesh entity id
Definition cs_defs.h:335
#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:186
cs_alloc_mode_t
Definition cs_mem.h:50