Skip to content

Commit 677de2a

Browse files
committed
Changed: Let the second argument of SystemMatrix::initAssembly()
be a char to enable forced preassembly in addition to delayed sparsity pattern lock. Forced preassembly is activated by num_threads_SLU equal to -2 (maybe a bit hacklish, but...). This is needed for the single-thread or non/optimized builds where the preassembly step normally is skipped.
1 parent b6f2c40 commit 677de2a

15 files changed

+56
-60
lines changed

src/ASM/AlgEqSystem.C

+4-3
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ bool AlgEqSystem::init (LinAlg::MatrixType mtype, const LinSolParams* spar,
3434
bool withReactions, int num_threads_SLU)
3535
{
3636
// Using the sign of the num_threads_SLU argument to flag this (convenience)
37-
bool dontLockSparsityPattern = num_threads_SLU < 0;
37+
char paFlag = num_threads_SLU == -2 ? 'f' : (num_threads_SLU < 0 ? 'd' : 0);
38+
if (num_threads_SLU < 0) num_threads_SLU = 1;
3839

3940
size_t i;
4041
for (i = nmat; i < A.size(); i++)
@@ -55,11 +56,11 @@ bool AlgEqSystem::init (LinAlg::MatrixType mtype, const LinSolParams* spar,
5556
if (spar)
5657
A[i]._A = SystemMatrix::create(adm,mtype,*spar);
5758
else
58-
A[i]._A = SystemMatrix::create(adm,mtype,abs(num_threads_SLU));
59+
A[i]._A = SystemMatrix::create(adm,mtype,num_threads_SLU);
5960
if (!A[i]._A) return false;
6061
}
6162

62-
A[i]._A->initAssembly(sam,dontLockSparsityPattern);
63+
A[i]._A->initAssembly(sam,paFlag);
6364
A[i]._b = nullptr;
6465
}
6566

src/LinAlg/DenseMatrix.C

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ DenseMatrix::DenseMatrix (const Matrix& A, bool s) : myMat(A)
7474
}
7575

7676

77-
void DenseMatrix::initAssembly (const SAM& sam, bool)
77+
void DenseMatrix::initAssembly (const SAM& sam, char)
7878
{
7979
myMat.resize(sam.neq,sam.neq,true);
8080
}

src/LinAlg/DenseMatrix.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class DenseMatrix : public SystemMatrix
7171

7272
//! \brief Initializes the element assembly process.
7373
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
74-
virtual void initAssembly(const SAM& sam, bool);
74+
virtual void initAssembly(const SAM& sam, char);
7575

7676
//! \brief Initializes the matrix to zero assuming it is properly dimensioned.
7777
virtual void init();

src/LinAlg/DiagMatrix.C

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ DiagMatrix::DiagMatrix (const RealArray& data, size_t nrows)
2424
}
2525

2626

27-
void DiagMatrix::initAssembly (const SAM& sam, bool)
27+
void DiagMatrix::initAssembly (const SAM& sam, char)
2828
{
2929
myMat.resize(sam.neq,true);
3030
}

src/LinAlg/DiagMatrix.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,8 @@ class DiagMatrix : public SystemMatrix
5858
const char* label);
5959

6060
//! \brief Initializes the element assembly process.
61-
//! \details Must be called once before the element assembly loop.
6261
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
63-
virtual void initAssembly(const SAM& sam, bool);
62+
virtual void initAssembly(const SAM& sam, char);
6463

6564
//! \brief Initializes the matrix to zero assuming it is properly dimensioned.
6665
virtual void init() { myMat.fill(Real(0)); }

src/LinAlg/ISTLMatrix.C

+9-9
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,18 @@ ISTLMatrix::~ISTLMatrix ()
117117
}
118118

119119

120-
void ISTLMatrix::initAssembly (const SAM& sam, bool delayLocking)
120+
void ISTLMatrix::initAssembly (const SAM& sam, char)
121121
{
122-
SparseMatrix::initAssembly(sam, delayLocking);
123-
SparseMatrix::preAssemble(sam, delayLocking);
122+
this->resize(sam.getNoEquations());
123+
this->preAssemble(sam,false);
124124

125-
std::vector<std::set<int>> dofc;
125+
std::vector<IntSet> dofc;
126126
sam.getDofCouplings(dofc);
127127

128128
// Set correct number of rows and columns for matrix.
129129
size_t sum = 0;
130-
for (const auto& it : dofc)
131-
sum += it.size();
130+
for (const IntSet& dofs : dofc)
131+
sum += dofs.size();
132132

133133
iA.setSize(rows(), cols(), sum);
134134
iA.setBuildMode(ISTL::Mat::random);
@@ -138,8 +138,8 @@ void ISTLMatrix::initAssembly (const SAM& sam, bool delayLocking)
138138
iA.endrowsizes();
139139

140140
for (size_t i = 0; i < dofc.size(); ++i)
141-
for (const auto& it : dofc[i])
142-
iA.addindex(i, it-1);
141+
for (int dof : dofc[i])
142+
iA.addindex(i,dof-1);
143143

144144
iA.endindices();
145145

@@ -159,7 +159,7 @@ bool ISTLMatrix::endAssembly()
159159

160160
void ISTLMatrix::init ()
161161
{
162-
SparseMatrix::init();
162+
this->SparseMatrix::init();
163163

164164
// Set all matrix elements to zero
165165
iA = 0;

src/LinAlg/ISTLMatrix.h

+1-4
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,9 @@ class ISTLMatrix : public SparseMatrix
102102
SystemMatrix* copy() const override { return new ISTLMatrix(*this); }
103103

104104
//! \brief Initializes the element assembly process.
105-
//! \details Must be called once before the element assembly loop.
106-
//! The PETSc data structures are initialized and the all symbolic operations
107105
//! that are needed before the actual assembly can start are performed.
108106
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
109-
//! \param[in] delayLocking If \e true, do not lock the sparsity pattern yet
110-
void initAssembly(const SAM& sam, bool delayLocking) override;
107+
void initAssembly(const SAM& sam, char) override;
111108

112109
//! \brief Initializes the matrix to zero assuming it is properly dimensioned.
113110
void init() override;

src/LinAlg/PETScMatrix.C

+5-8
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,11 @@ PETScMatrix::~PETScMatrix ()
169169
}
170170

171171

172-
void PETScMatrix::initAssembly (const SAM& sam, bool delayLocking)
172+
void PETScMatrix::initAssembly (const SAM& sam, char)
173173
{
174-
if (adm.dd.isPartitioned())
175-
this->resize(sam.neq,sam.neq);
176-
else {
177-
this->SparseMatrix::initAssembly(sam, delayLocking);
178-
this->SparseMatrix::preAssemble(sam, delayLocking);
179-
}
174+
this->resize(sam.neq,sam.neq);
175+
if (!adm.dd.isPartitioned())
176+
this->preAssemble(sam,false);
180177

181178
// Get number of local equations in linear system
182179
PetscInt neq = adm.dd.getMaxEq() - adm.dd.getMinEq() + 1;
@@ -220,7 +217,7 @@ void PETScMatrix::initAssembly (const SAM& sam, bool delayLocking)
220217
isvec.resize(adm.dd.getNoBlocks());
221218
// index sets
222219
for (size_t i = 0; i < isvec.size(); ++i) {
223-
std::vector<int> blockEq;
220+
IntVec blockEq;
224221
blockEq.reserve(adm.dd.getMaxEq(i+1)-adm.dd.getMinEq(i+1)+1);
225222
for (int leq : adm.dd.getBlockEqs(i)) {
226223
int eq = adm.dd.getGlobalEq(leq);

src/LinAlg/PETScMatrix.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ class PETScMatrix : public SparseMatrix
100100
LinAlg::MatrixType getType() const override { return LinAlg::PETSC; }
101101

102102
//! \brief Initializes the element assembly process.
103+
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
104+
//!
103105
//! \details Must be called once before the element assembly loop.
104106
//! The PETSc data structures are initialized and the all symbolic operations
105107
//! that are needed before the actual assembly can start are performed.
106-
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
107-
//! \param[in] delayLocking If \e true, do not lock the sparsity pattern yet
108-
void initAssembly(const SAM& sam, bool delayLocking) override;
108+
void initAssembly(const SAM& sam, char) override;
109109

110110
//! \brief Initializes the matrix to zero assuming it is properly dimensioned.
111111
void init() override;

src/LinAlg/SPRMatrix.C

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ size_t SPRMatrix::dim (int idim) const
196196
that are need before the actual assembly can start are performed.
197197
*/
198198

199-
void SPRMatrix::initAssembly (const SAM& sam, bool)
199+
void SPRMatrix::initAssembly (const SAM& sam, char)
200200
{
201201
memset(mpar,0,NS*sizeof(int));
202202
msica = msifa = mtrees = mvarnc = nullptr;

src/LinAlg/SPRMatrix.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class SPRMatrix : public SystemMatrix
4848

4949
//! \brief Initializes the element assembly process.
5050
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
51-
virtual void initAssembly(const SAM& sam, bool);
51+
virtual void initAssembly(const SAM& sam, char);
5252

5353
//! \brief Initializes the matrix to zero assuming it is properly dimensioned.
5454
virtual void init();

src/LinAlg/SparseMatrix.C

+14-18
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,8 @@ SparseMatrix::SparseMatrix (SparseSolver eqSolver, int nt)
145145
nrow = ncol = 0;
146146
solver = eqSolver;
147147
numThreads = nt;
148-
#ifdef HAS_UMFPACK
149-
umfSymbolic = nullptr;
150-
#endif
151148
slu = nullptr;
149+
umfSymbolic = nullptr;
152150
}
153151

154152

@@ -161,9 +159,7 @@ SparseMatrix::SparseMatrix (size_t m, size_t n)
161159
solver = NONE;
162160
numThreads = 0;
163161
slu = nullptr;
164-
#ifdef HAS_UMFPACK
165162
umfSymbolic = nullptr;
166-
#endif
167163
}
168164

169165

@@ -177,9 +173,7 @@ SparseMatrix::SparseMatrix (const SparseMatrix& B)
177173
solver = B.solver;
178174
numThreads = B.numThreads;
179175
slu = nullptr; // The SuperLU data (if any) is not copied
180-
#ifdef HAS_UMFPACK
181-
umfSymbolic = nullptr;
182-
#endif
176+
umfSymbolic = nullptr; // The UMFPACK data (if any) is not copied
183177
}
184178

185179

@@ -210,6 +204,7 @@ bool SparseMatrix::lockPattern (bool doLock)
210204
void SparseMatrix::resize (size_t r, size_t c, bool forceEditable)
211205
{
212206
factored = false;
207+
if (c == 0) c = r;
213208
if (r == nrow && c == ncol && !forceEditable)
214209
{
215210
// Clear the matrix content but retain its sparsity pattern
@@ -227,15 +222,14 @@ void SparseMatrix::resize (size_t r, size_t c, bool forceEditable)
227222
A.clear();
228223

229224
nrow = r;
230-
ncol = c > 0 ? c : r;
225+
ncol = c;
231226

232227
delete slu;
233228
slu = nullptr;
234229
#ifdef HAS_UMFPACK
235-
if (umfSymbolic) {
230+
if (umfSymbolic)
236231
umfpack_di_free_symbolic(&umfSymbolic);
237-
umfSymbolic = nullptr;
238-
}
232+
umfSymbolic = nullptr;
239233
#endif
240234
}
241235

@@ -477,8 +471,8 @@ bool SparseMatrix::augment (const SystemMatrix& B, size_t r0, size_t c0)
477471

478472
for (const ValueMap::value_type& val : Bptr->elem)
479473
{
480-
elem[std::make_pair(r0+val.first.first,c0+val.first.second)] += val.second;
481-
elem[std::make_pair(c0+val.first.second,r0+val.first.first)] += val.second;
474+
elem[{ r0+val.first.first, c0+val.first.second }] += val.second;
475+
elem[{ c0+val.first.second, r0+val.first.first }] += val.second;
482476
}
483477

484478
return true;
@@ -736,12 +730,14 @@ static void assemSparse (const RealArray& V, SparseMatrix& SM, size_t col,
736730
}
737731

738732

739-
void SparseMatrix::initAssembly (const SAM& sam, bool delayLocking)
733+
void SparseMatrix::initAssembly (const SAM& sam, char preAssembly)
740734
{
741735
this->resize(sam.neq,sam.neq);
736+
if (preAssembly == 'f')
737+
this->preAssemble(sam,false);
742738
#ifdef USE_OPENMP
743-
if (omp_get_max_threads() > 1)
744-
this->preAssemble(sam,delayLocking);
739+
else if (omp_get_max_threads() > 1)
740+
this->preAssemble(sam,preAssembly=='d');
745741
#endif
746742
}
747743

@@ -758,7 +754,7 @@ void SparseMatrix::preAssemble (const SAM& sam, bool delayLocking)
758754

759755
// If we are not locking the sparsity pattern yet, the index pair map over
760756
// the non-zero matrix elements needs to be initialized before the assembly.
761-
// This is used when SAM::getDofCouplings does not return all connectivities
757+
// This is used when SAM::getDofCouplings() does not return all connectivities
762758
if (delayLocking) // that will exist in the final matrix.
763759
for (size_t i = 0; i < dofc.size(); i++)
764760
for (int j : dofc[i])

src/LinAlg/SparseMatrix.h

+7-6
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,12 @@ class SparseMatrix : public SystemMatrix
105105

106106
//! \brief Initializes the element assembly process.
107107
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
108-
//! \param[in] delayLocking If \e true, do not lock the sparsity pattern yet
109-
virtual void initAssembly(const SAM& sam, bool delayLocking);
108+
//! \param[in] preAssembly Flag for doing preassembly
109+
//! - f : Force preassembly always, and lock the sparsity pattern
110+
//! - d : Do preassembly only if multi-threaded assembly,
111+
//! but delay locking the sparsity pattern
112+
//! - 0 : Do preassembly if multi-threading, and lock parsity pattern
113+
virtual void initAssembly(const SAM& sam, char preAssembly);
110114

111115
//! \brief Initializes the element sparsity pattern based on node connections.
112116
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
@@ -275,10 +279,7 @@ class SparseMatrix : public SystemMatrix
275279
SparseSolver solver; //!< Which equation solver to use
276280
SuperLUdata* slu; //!< Matrix data for the SuperLU equation solver
277281
int numThreads; //!< Number of threads to use for the SuperLU_MT solver
278-
279-
#ifdef HAS_UMFPACK
280-
void* umfSymbolic; //!< Symbolically factored matrix for UMFPACK
281-
#endif
282+
void* umfSymbolic; //!< Symbolically factored matrix for UMFPACK
282283

283284
protected:
284285
bool factored; //!< Set to \e true when the matrix is factorized

src/LinAlg/SystemMatrix.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,9 @@ class SystemMatrix
230230

231231
//! \brief Initializes the element assembly process.
232232
//! \param[in] sam Auxiliary data describing the FE model topology, etc.
233-
//! \param[in] delayLocking If \e true, do not lock the sparsity pattern yet
234233
//!
235234
//! \details This method must be called once before the element assembly loop.
236-
virtual void initAssembly(const SAM& sam, bool delayLocking = false) = 0;
235+
virtual void initAssembly(const SAM& sam, char = 0) = 0;
237236

238237
//! \brief Initializes the matrix to zero assuming it is properly dimensioned.
239238
virtual void init() = 0;

src/SIM/SIMinput.C

+6
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,12 @@ bool SIMinput::parseGeometryTag (const tinyxml2::XMLElement* elem)
368368
IFEM::cout <<"\tActivation function for P"<< patch
369369
<<": "<< funcdef << std::endl;
370370
pch->setElementActivator(utl::parseIntFunc(funcdef,type));
371+
#ifndef USE_OPENMP
372+
// Force pre-assembly also for Debug and Nopt builds, such that
373+
// the final sparsity pattern is established up front when not
374+
// all elements are active in the first step/iteration
375+
opt.num_threads_SLU = -2;
376+
#endif
371377
}
372378
}
373379

0 commit comments

Comments
 (0)