CEPS  24.01
Cardiac ElectroPhysiology Simulator
DistributedHaloVector.cpp
Go to the documentation of this file.
1 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2  This file is part of CEPS.
3 
4  CEPS is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  CEPS is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with CEPS (see file LICENSE at root of project).
16  If not, see <https://www.gnu.org/licenses/>.
17 
18 
19  Copyright 2019-2024 Inria, Universite de Bordeaux
20 
21  Authors, in alphabetical order:
22 
23  Pierre-Elliott BECUE, Florian CARO, Yves COUDIERE(*), Andjela DAVIDOVIC,
24  Charlie DOUANLA-LONTSI, Marc FUENTES, Mehdi JUHOOR, Michael LEGUEBE(*),
25  Pauline MIGERDITICHAN, Valentin PANNETIER(*), Nejib ZEMZEMI.
26  * : currently active authors
27 
28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
31 
32 #ifdef CEPS_USE_PETSC
33 
35 {
36  initialize();
37 }
38 
40 {
41  initialize();
42  // call assignment operator
43  *this = v;
44 }
45 
47  CepsIndex M,
48  CepsIndex m,
49  CepsIndex nbHaloRows,
50  CepsIndex* haloRows
51 ) :
52  m_nbHaloRows(nbHaloRows)
53 {
54  this->m_isAssembled = false;
55  this->m_mayReadData = false;
56 
57  // create the vector with halo padding
58  VecCreateGhost(ceps::getCommunicator(), m, M, nbHaloRows, haloRows, &(this->m_v));
59  m_vecCreated = true;
60 
61  #ifdef PROFILING_VECTOR
62  m_totalAssembly = m_tickAssembly = 0.0;
63  #endif
64 
65  // update local copy of row ownership
66  VecGetOwnershipRange(this->m_v, &(this->m_lo), &(this->m_hi));
67  CepsIndex sum = 0;
68  // mapping non-ghost values
69  for (CepsIndex i = 0; i < m; i++, sum++)
70  m_globalToLocalMapping[this->m_lo + i] = sum;
71 
72  // Mapping ghots values:
73  // they are always located after the non-ghost values
74  for (CepsIndex i = 0; i < nbHaloRows; i++, sum++)
75  m_globalToLocalMapping[haloRows[i]] = sum;
76 
77  CEPS_ABORT_IF((this->m_hi - this->m_lo + nbHaloRows) != sum
78  or (CepsIndex) m_globalToLocalMapping.size () != sum,
79  "DistributedHaloVector: fatal error, some DsOF were not mapped."
80  );
81 
82  // Now ok to use this vector
83  this->m_initialized = true;
84  this->m_globalSize = M;
85  this->m_localSize = m;
86 }
87 
89 {
90 }
91 
92 void
94 {
95  // Scatter the proper values before accessing the values.
96  // Here, the scatter is forward, meaning the halo values
97  // are set to the correct value from the owning processes:
98  // i.e., any local modification in the halo rows is overwritten.
99  VecGhostUpdateBegin(m_v,INSERT_VALUES,SCATTER_FORWARD);
100  VecGhostUpdateEnd (m_v,INSERT_VALUES,SCATTER_FORWARD);
101 
102  // Get the local representation of this vector
103  VecGhostGetLocalForm(this->m_v,&m_localV);
104  // Ok to get the local array
105  VecGetArray(m_localV, &(this->m_localData));
106 
107  // ok to read data now
108  this->m_mayReadData = true;
109 }
110 
111 void
113 {
114  this->m_mayReadData = false;
115  VecRestoreArray(m_localV, &(this->m_localData));
116  VecGhostRestoreLocalForm(this->m_v, &m_localV);
117 }
118 
119 void
121 {
122 
124  "Invalid access to local data.\n"
125  " Make sure you called DistributedVector::getLocalData() beforehand."
126  );
127 
128  // Use the global to local mapping:
129  // iterate on every global index parameter and check if
130  // current process has it in local memory
131  std::map<CepsIndex, CepsIndex>::iterator it;
132  for (CepsIndex i = 0; i < n; i++)
133  {
134  it = m_globalToLocalMapping.find (indices[i]);
135  // failure if current process does not own this row
137  "Distributed vector: on process #" << ceps::getRank() << ", trying to access row #"
138  << indices[i] << "\nwhich not local or halo."
139  );
140 
141  // Now ok to read in local memory
142  values[i] = this->m_localData[it->second];
143  }
144 }
145 
146 CepsInt
148 {
149  return m_nbHaloRows;
150 }
151 
152 void
154 {
155  m_mayReadData = false;
156  m_initialized = false;
157  m_isAssembled = false;
159  #ifdef PROFILING_VECTOR
160  m_totalAssembly = m_tickAssembly = 0.0;
161  #endif
162 }
163 
164 // OPERATORS
165 // non const version
166 CepsReal&
168 {
169  std::map<CepsIndex, CepsIndex>::iterator it = m_globalToLocalMapping.find(index);
170 
172  "access to memory not requested"
173  );
175  "out-of-bounds index " << index
176  );
177 
178  return this->m_localData[it->second];
179 }
180 
181 // const version
182 CepsReal
184 {
185  std::map<CepsIndex, CepsIndex>::const_iterator it = m_globalToLocalMapping.find(index);
186 
187 // NO : getReleaseLocalData not const compatible
188 //#ifdef CEPS_DEBUG_ENABLED
189 // if (not m_mayReadData)
190 // CEPS_ABORT ("DistributedHaloVector: access to memory not requested.");
191 //#endif // CEPS_DEBUG_ENABLED
192 
194  "out-of-bounds index " << index
195  );
196 
197  return this->m_localData[it->second];
198 }
199 
202 {
204  "source vector is not initialized"
205  );
206 
207  // duplicate
208  if (not m_initialized)
209  v.duplicate(*this,false);
210  // copy
211  CepsIndex size = v.m_hi-v.m_lo+v.m_nbHaloRows;
212  v.getLocalData();
213  getLocalData ();
214  CepsReal *source = v.localData();
215  CepsReal *dest = localData ();
216  memcpy(dest,source,size*sizeof(CepsReal));
217  v.releaseLocalData();
218  releaseLocalData ();
219 
220  // copy the mapping
222  // copy the number of halo rows
224 
225  // ok to use it now
226  m_initialized = true;
227 
228  return *this;
229 }
230 
233 {
235  "calling vector is not initialized"
236  );
237  CepsIndex hi,lo;
238  v.getLocalRange(&lo,&hi);
239  CEPS_ABORT_IF((lo != m_lo) or (hi != m_hi),
240  "vectors are of different sizes"
241  );
242 
243  v.getLocalData ();
244  this->getLocalData();
245  CepsReal *source = v .localData();
246  CepsReal *dest = this->localData();
247  memcpy(dest,source,(hi-lo)*sizeof(CepsReal));
248  v .releaseLocalData();
249  this->releaseLocalData();
250 
251  // ok to use it now
252  m_initialized = true;
253 
254  return *this;
255 }
256 
257 void
259 {
260  #ifdef CEPS_USE_PETSC
261  VecScale(m_localV,alpha);
262  #endif
263  return;
264 }
265 
266 void
268 {
270  #ifdef CEPS_USE_PETSC
271  VecAbs(m_localV);
272  #endif
273  return;
274 }
275 
276 #endif // CEPS_USE_PETSC
#define CEPS_ABORT_IF(condition, message)
Stops the execution with a message if condition is true. If testing is enabled, only throws a runtime...
float CepsReal
Need single precision floating point.
Definition: CepsTypes.hpp:100
int32_t CepsInt
Need 32 bit integer.
Definition: CepsTypes.hpp:106
CepsInt CepsIndex
Index rowid etc.
Definition: CepsTypes.hpp:111
Extended distributed vectors.
std::map< CepsIndex, CepsIndex > m_globalToLocalMapping
Index mapping.
~DistributedHaloVector() override
Destructor.
void getLocalData() override
Mandatory call before accessing data.
CepsInt getNbHalo()
number of halo values
void scale(CepsMathScalar alpha) override
Multiplies self by alpha.
void abs() override
Sets all coeffs to their absolute value.
CepsReal & operator[](CepsIndex globalIndex) override
Array subscription override.
DistributedHaloVector()
Default constructor.
PetscVector m_localV
Local representation of the halo vector.
void releaseLocalData() override
Mandatory call after accessing data.
CepsIndex m_nbHaloRows
Number of halo values that will be received.
DistributedHaloVector & operator=(DistributedHaloVector &v)
Assignment operator.
void getValues(CepsReal *values, CepsIndex n, const CepsIndex *indices) override
Override of parent DistributedVector::getValues(...)
Structure to hold spatially dependant data and distribute it between process.
CepsMathScalar * m_localData
virtual void getLocalData()
Enables direct access to the stored local values.
CepsBool m_initialized
Whether this vector is ready to be used or not.
CepsBool m_isAssembled
Whether this vector is assembled or not.
PetscVector m_v
The underlying vector.
CepsGlobalIndex m_lo
Index of first owned row.
CepsMathScalar * localData()
Point on the local data.
void duplicate(DistributedVector &dest, CepsBool copyValues) const
Shares the non-zero structure, and optionally values.
CepsGlobalIndex m_hi
Index of row right after last owned row.
virtual void releaseLocalData()
Release the pointer on the local data.
CepsInt m_globalSize
Global size of vector.
void getLocalRange(CepsGlobalIndex *lo, CepsGlobalIndex *hi) const
Get the range of rows owned by current process.
virtual void abs()
Every component of the vector is replaced by its absolute value.
CepsInt m_localSize
Local size of vector.
CepsUInt getRank()
Returns current processor rank.
MPI_Comm getCommunicator()
Get the communicator.