TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
IJK_Field_local_template.tpp
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#ifndef IJK_Field_local_template_TPP_H
17#define IJK_Field_local_template_TPP_H
18
19#include <Simd_template.h>
20
21// External storage: false=>normal behaviour, true=>the field will not allocate memory in data_, the user must
22// provide the storage via set_external_storage() method (used to map memory from elsewhere).
23// Example: field.allocate(... , true); int size=field.get_allocated_size(); Array T(size); field.set_external_storage(T);
24// IMPORTANT: when "external_storage==false", an appropriate offset will be set in order to align the data on cache lines,
25// (this offset varies from field to field even if the field shape (ni,nj,nk,compo,ghost) is exactly the same
26// plus extra padding will be added to align all i=0,j,k on SIMD aligned blocks...
27template<typename _TYPE_, typename _TYPE_ARRAY_>
28void IJK_Field_local_template<_TYPE_,_TYPE_ARRAY_>::allocate(int Ni, int Nj, int Nk, int ghosts, int additional_k_layers, int nb_compos, bool external_storage)
29{
30 // WARNING !!!
31 // for the sympy_to_trust system, mem alignment must be disabled otherwise we have serious trouble
32 // with fields of same "kind" that have not the same storage pattern (offset, stride, etc...), and
33 // we heavily rely on "same pattern" to optimize fetch operations in the fields...
34 bool disable_memalign = true;
35 if (ghosts > Ni || ghosts > Nj || ghosts > Nk)
36 {
37 Cerr << "Error in IJK_Field_local_template::allocate: ghostsize=" << ghosts << " is larger than the local mesh size " << Ni << " " << Nj << " " << Nk << finl;
39 }
40 ni_ = Ni;
41 nj_ = Nj;
42 nk_ = Nk;
43 ghost_size_ = ghosts;
44 this->nb_compo_ = nb_compos;
45 j_stride_ = ni_ + 2 * ghosts;
46 if (!external_storage || disable_memalign)
47 // Align beginning of line on SIMD type...
49 j_stride_++;
50 compo_stride_ = j_stride_ * (nj_ + 2 * ghosts);
53 additional_k_layers_ = additional_k_layers;
54 int sz = (nk_ + 2 * ghosts + additional_k_layers) * compo_stride_ * this->nb_compo_ + 1;
57 if (!external_storage || disable_memalign)
58 {
59 // Ensure that there is some padding data at beginning:
60 offset_ += 8;
61
62 // Align origin on cache line boundary
63 const int CacheLineSizeBytes = 64;
64 sz += (int)(CacheLineSizeBytes/sizeof(_TYPE_));
65 // Add supplemental data at end for the last SIMD instruction of the loop that might go
66 // beyond the end of the usefull data
67 sz += (int)(CacheLineSizeBytes/sizeof(_TYPE_));
68
69 allocated_size_ = sz;
70 _TYPE_ *ptr = data_.addr() + offset_;
71 char *cptr = (char *) ptr;
72 long long iptr = (long long) cptr;
73 long long decal = iptr & (CacheLineSizeBytes - 1);
74 offset_ += (int)((CacheLineSizeBytes - decal) / sizeof(_TYPE_));
75 }
76 if (!external_storage)
77 data_.resize_array(sz);
78
79}
80
81// Adds n * compo_stride_ * nb_compo_ to the offset (shifts the data by n layers in the k direction without moving memory)
82// Used by the jacobi "in place" algorithm: the result replaces the source data but is shifted in k.
83template<typename _TYPE_, typename _TYPE_ARRAY_>
85{
86 k_layer_shift_ += n;
87 // Check that the data still fits into the allocated memory block
89
90 offset_ += compo_stride_ * this->nb_compo_ * n;
91}
92
93// Creates a field with nk=1, that points to the data than src(...,...,k_layer) (uses ref_array() to create the reference).
94// ghostsize is identical to source array.
95template<>
96inline void IJK_Field_local_template<float,ArrOfFloat>::ref_ij(IJK_Field_local_float& src, int k_lay)
97{
98 Cerr << "Error: must implement ArrOfFloat::ref_array() and reset()" << finl;
100}
101
102template<>
103inline void IJK_Field_local_template<double, ArrOfDouble>::ref_ij(IJK_Field_local_double& src, int k_lay)
104{
105 data_.reset();
106 ni_ = src.ni_;
107 nj_ = src.nj_;
108 nk_ = 1;
110 j_stride_ = src.j_stride_;
111 this->nb_compo_ = 1;
112 compo_stride_ = 0;
113 k_layer_shift_ = 0;
115
116 const int i_first = src.linear_index(-ghost_size_, -ghost_size_, k_lay);
117 const int i_last = src.linear_index(ni_ + ghost_size_ - 1, nj_ + ghost_size_ - 1, k_lay);
118 offset_ = src.linear_index(0, 0, k_lay) - i_first;
119 data_.ref_array(src.data_, i_first, i_last - i_first + 1);
120}
121
122
123
124#endif /* IJK_Field_local_template_TPP_H */
int nb_compo_
Definition Field_base.h:95
void allocate(int ni, int nj, int nk, int ghosts, int additional_k_layers=0, int nb_compo=1, bool external_storage=false)
int linear_index(int i, int j, int k) const
void ref_ij(IJK_Field_local_template &src, int k_layer)
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int size()