NeoPZ
tpzdohrmatrix.cpp
Go to the documentation of this file.
1 
6 #include "tpzdohrmatrix.h"
7 
8 #include "tpzdohrassembly.h"
9 #include "pzlog.h"
10 
11 #include "TPZfTime.h"
12 #include "TPZTimeTemp.h"
13 
14 #include "pz_pthread.h"
15 
16 #include "tpzparallelenviroment.h"
17 
18 #ifdef LOG4CXX
19 static LoggerPtr logger(Logger::getLogger("substruct.dohrsubstruct"));
20 #endif
21 
22 
23 template<class TVar, class TSubStruct>
25 : TPZMatrix<TVar>(), fNumThreads(0), fAssembly(assembly)
26 {
27 }
28 
29 template<class TVar, class TSubStruct>
31 {
32 }
33 
36 #ifdef USING_TBB
37 #include <tbb/parallel_for.h>
38 #include <tbb/blocked_range.h>
39 #include <tbb/partitioner.h>
40 using namespace tbb;
41 #endif
42 
43 #include "arglib.h"
44 
45 template<class TVar, class TSubStruct>
47 {
48 private:
50  std::vector<TPZDohrThreadMultData<TSubStruct> > mWorkItems;
51 
55  TVar fAlpha;
57  pthread_mutex_t fAccessLock;
61  std::list<TPZDohrThreadMultData<TSubStruct> > fWork;
64 
65 
66 
67 public:
68 
70  ParallelAssembleTaskMatrix(const TPZFMatrix<TVar> &x, TVar alpha, TPZAutoPointer<TPZDohrAssembly<TVar> > assembly, TPZAutoPointer<TPZDohrAssembleList<TVar> > &assemblestruct) : fInput(&x), fAlpha(alpha), fAssembly(assembly), fAssemblyStructure(assemblestruct) {};
71 
74  mWorkItems.push_back(data);
75  }
76 
77 #ifdef USING_TBB
78 
79  void operator()(const blocked_range<size_t>& range) const
80  {
81 
82  for(size_t i=range.begin(); i!=range.end(); ++i )
83  {
84  TPZDohrThreadMultData<TSubStruct> runner = mWorkItems[i];
85  TPZFMatrix<TVar> xlocal;
86  fAssembly->Extract(runner.fisub,*(fInput),xlocal);
87  TPZAutoPointer<TPZDohrAssembleItem<TVar> > assembleItem = new TPZDohrAssembleItem<TVar>(runner.fisub,xlocal.Rows(),xlocal.Cols());
88  runner.fSub->ContributeKULocal(fAlpha,xlocal,assembleItem->fAssembleData);
89  fAssemblyStructure->AddItem(assembleItem);
90  }
91  }
92 
94  void run_parallel_for(affinity_partitioner &ap)
95  {
96  /* TBB Parallel for. It will split the range
97  * into N sub-ranges and
98  * invoke the operator() for each sub-range.
99  */
100  parallel_for(blocked_range<size_t>(0, mWorkItems.size()), *this, ap);
101  }
102 #endif
103 
104 
105 }; /* ParallelAssembleTask */
106 
107 template<class TVar, class TSubStruct>
109  const TVar alpha,const TVar beta,const int opt) const
110 {
111 
112 #ifdef USING_TBB
113 
114  if ((!opt && this->Cols() != x.Rows()) || this->Rows() != x.Rows())
115  this->Error( "Operator* <matrixs with incompatible dimensions>" );
116  if(x.Cols() != y.Cols() || x.Cols() != z.Cols() || x.Rows() != y.Rows() || x.Rows() != z.Rows()) {
117  this->Error ("TPZFMatrix::MultiplyAdd incompatible dimensions\n");
118  }
119  this->PrepareZ(y,z,beta,opt);
120 
121 
122  unsigned int nglob = fGlobal.size();
124 
125  ParallelAssembleTaskMatrix<TVar,TSubStruct> multwork(x,alpha,fAssembly,assemblelist);
126  typename std::list<TPZAutoPointer<TSubStruct> >::const_iterator iter;
127  int isub=0;
128  for (iter=fGlobal.begin(); iter!=fGlobal.end(); iter++,isub++) {
129  TPZDohrThreadMultData<TSubStruct> data(isub,*iter);
130 
131  multwork.addWorkItem(data);
132  }
133  TPZVec<pthread_t> AllThreads(1);
134 
135  multwork.run_parallel_for(pzenviroment.fSubstructurePartitioner);
136 
138  assemblelist.operator->(), __FUNCTION__);
139 
140  void *result;
141  PZ_PTHREAD_JOIN(AllThreads[0], &result, __FUNCTION__);
142 #endif
143 
144 }
145 
146 
147 template<class TVar, class TSubStruct>
149  const TVar alpha,const TVar beta,const int opt) const
150 {
151 
152 #ifdef USING_TBB
153  MultAddTBB(x, y, z, alpha, beta, opt);
154  return;
155 #endif
156 
157  TPZfTime mult;
158  if ((!opt && this->Cols() != x.Rows()) || this->Rows() != x.Rows())
159  this->Error( "Operator* <matrixs with incompatible dimensions>" );
160  if(x.Cols() != y.Cols() || x.Cols() != z.Cols() || x.Rows() != y.Rows() || x.Rows() != z.Rows()) {
161  this->Error ("TPZFMatrix::MultiplyAdd incompatible dimensions\n");
162  }
163  this->PrepareZ(y,z,beta,opt);
164 
165  typename SubsList::const_iterator iter;
166  int isub = 0;
167  if (fNumThreads == 0) {
168  for (iter=fGlobal.begin();iter!=fGlobal.end();iter++,isub++) {
169  if(0)
170  {
174  TPZAutoPointer<TSubStruct> point(*iter);
175  TPZPersistenceManager::WriteToFile(point.operator ->());
177 
178  }
179  TPZFMatrix<TVar> xlocal,zlocal;
180  fAssembly->Extract(isub,x,xlocal);
181  zlocal.Redim(xlocal.Rows(),xlocal.Cols());
182  (*iter)->ContributeKULocal(alpha,xlocal,zlocal);
183  fAssembly->Assemble(isub,zlocal,z);
184  // z.Print("Resultado intermediario");
185  }
186  }
187  else {
188  unsigned int nglob = fGlobal.size();
190 
191  TPZDohrThreadMultList<TVar,TSubStruct> multwork(x,alpha,fAssembly,assemblelist);
192  typename std::list<TPZAutoPointer<TSubStruct> >::const_iterator iter;
193  int isub=0;
194  for (iter=fGlobal.begin(); iter!=fGlobal.end(); iter++,isub++) {
195  TPZDohrThreadMultData<TSubStruct> data(isub,*iter);
196 
197  multwork.AddItem(data);
198  }
199  TPZVec<pthread_t> AllThreads(fNumThreads+1);
200  int i;
201  for (i=0; i<fNumThreads; i++) {
203  &multwork, __FUNCTION__);
204  }
205  //sleep(1);
207  assemblelist.operator->(), __FUNCTION__);
208 
209  for (i=0; i<fNumThreads+1; i++) {
210  void *result;
211  PZ_PTHREAD_JOIN(AllThreads[i], &result, __FUNCTION__);
212  }
213  }
215 }
216 
217 template<class TVar, class TSubStruct>
219 {
220  std::cout << "Number of substructures " << fGlobal.size() << std::endl;
221  tempo.fNumSub = fGlobal.size(); // alimenta timeTemp com o numero de substruturas
222  TPZFMatrix<TVar> diag(this->Rows(),1,0.);
223  typename SubsList::iterator iter;
224  int isub = 0;
225  for (iter=fGlobal.begin();iter!=fGlobal.end();iter++,isub++) {
226  //Basic initialization for each substructure (compute the matrices)
227  //(*iter)->Initialize();
228  TPZFMatrix<TVar> diaglocal;
229  (*iter)->ContributeDiagonalLocal(diaglocal);
230  LOGPZ_DEBUG(logger,"Before assemble diagonal")
231  this->fAssembly->Assemble(isub,diaglocal,diag);
232 #ifdef LOG4CXX
233  {
234  std::stringstream sout;
235  sout << "Substructure " << isub << " ";
236  diag.Print("Global Diagonal matrix",sout);
237  LOGPZ_DEBUG(logger,sout.str())
238  }
239 #endif
240  std::cout << '*';
241  std::cout.flush();
242  }
243 #ifdef LOG4CXX
244  {
245  std::stringstream sout;
246  diag.Print("Global Diagonal matrix",sout);
247  LOGPZ_DEBUG(logger,sout.str())
248  }
249 #endif
250  std::cout << std::endl;
251  for (iter=fGlobal.begin(),isub=0;iter!=fGlobal.end();iter++,isub++) {
252  //Computes the Weights for each substructure
253  TPZFMatrix<TVar> diaglocal;
254  this->fAssembly->Extract(isub,diag,diaglocal);
255  (*iter)->ComputeWeightsLocal(diaglocal);
256 
257  }
258 }
259 
263 template<class TVar, class TSubStruct>
265 {
266  typename SubsList::iterator iter;
267  for (iter=fGlobal.begin();iter!=fGlobal.end();iter++) {
268  (*iter)->AdjustResidual(res);
269  }
270 }
271 
275 template<class TVar, class TSubStruct>
277 {
278  typename SubsList::iterator iter;
279  for (iter=fGlobal.begin();iter!=fGlobal.end();iter++) {
280  (*iter)->AddInternalSolution(solution);
281  }
282 }
283 
284 template<class TVar, class TSubStruct>
286 {
288  TPZDohrThreadMultData<TSubStruct> runner = myptr->PopItem();
289  while (runner.IsValid()) {
290  TPZFMatrix<TVar> xlocal;
291  myptr->fAssembly->Extract(runner.fisub,*(myptr->fInput),xlocal);
292  TPZAutoPointer<TPZDohrAssembleItem<TVar> > assembleItem = new TPZDohrAssembleItem<TVar>(runner.fisub,xlocal.Rows(),xlocal.Cols());
293  runner.fSub->ContributeKULocal(myptr->fAlpha,xlocal,assembleItem->fAssembleData);
294  myptr->fAssemblyStructure->AddItem(assembleItem);
295  runner = myptr->PopItem();
296  }
297  return ptr;
298 }
299 
305 template <class TVar, class TSubStruct>
307 {
308  SAVEABLE_SKIP_NOTE(buf);
309  TPZMatrix<TVar>::Read(buf, context);
310  SAVEABLE_SKIP_NOTE(buf);
311  fAssembly = TPZAutoPointerDynamicCast<TPZDohrAssembly<TVar>>(TPZPersistenceManager::GetAutoPointer(&buf));
312  SAVEABLE_SKIP_NOTE(buf);
313  buf.Read(&fNumCoarse);
314  SAVEABLE_SKIP_NOTE(buf);
315  buf.Read(&fNumThreads);
316  int sz;
317  SAVEABLE_SKIP_NOTE(buf);
318  buf.Read(&sz);
319  for (int i=0; i<sz; i++) {
320  TPZAutoPointer<TSubStruct > sub = new TSubStruct;
321  SAVEABLE_SKIP_NOTE(buf);
322  sub->Read(buf,0);
323  fGlobal.push_back(sub);
324  }
325  int classid;
326  SAVEABLE_SKIP_NOTE(buf);
327  buf.Read(&classid );
328  if (classid != ClassId()) {
329  DebugStop();
330  }
331 }
337 template <class TVar, class TSubStruct>
338 void TPZDohrMatrix<TVar,TSubStruct >::Write( TPZStream &buf, int withclassid ) const
339 {
340  SAVEABLE_STR_NOTE(buf,"TPZMatrix<TVar>::Write ()");
341  TPZMatrix<TVar>::Write(buf, withclassid);
342  SAVEABLE_STR_NOTE(buf,"fAssembly->Write");
343  TPZPersistenceManager::WritePointer(fAssembly.operator ->(), &buf);
344  SAVEABLE_STR_NOTE(buf,"fNumCoarse");
345  buf.Write(&fNumCoarse);
346  SAVEABLE_STR_NOTE(buf,"fNumThreads");
347  buf.Write(&fNumThreads);
348  int size = fGlobal.size();
349  SAVEABLE_STR_NOTE(buf,"fGlobal.size()");
350  buf.Write(&size);
351  for (auto it=fGlobal.begin(); it != fGlobal.end(); it++) {
352  SAVEABLE_STR_NOTE(buf,"fGlobal[...]");
353  (*it)->Write(buf,0);
354  }
355  size = 0;
356  int classid = ClassId();
357  SAVEABLE_STR_NOTE(buf,"ClassId");
358  buf.Write(&classid );
359 }
360 
361 template <>
363 {
364  DebugStop();
365 }
366 template <>
368 {
369  DebugStop();
370 }
371 template <>
373 {
374  DebugStop();
375 }
376 template <>
378 {
379  DebugStop();
380 }
381 
382 template <>
384 {
385  DebugStop();
386 }
387 template <>
389 {
390  DebugStop();
391 }
392 template <>
394 {
395  DebugStop();
396 }
397 template <>
399 {
400  DebugStop();
401 }
402 
403 
407 
411 
412 //template class TPZDohrMatrix<std::complex<float>, TPZDohrSubstruct<std::complex<float> > >;
414 //template class TPZDohrMatrix<std::complex<long double>, TPZDohrSubstruct<std::complex<long double> > >;
415 
416 //template class TPZDohrMatrix<std::complex<float>, TPZDohrSubstructCondense<std::complex<float> > >;
418 //template class TPZDohrMatrix<std::complex<long double>, TPZDohrSubstructCondense<std::complex<long double> > >;
419 
420 #ifndef BORLAND
425 #endif
void AdjustResidual(TPZFMatrix< TVar > &res)
Adjust the residual to zero the residual of the internal connects.
const TPZFMatrix< TVar > * fInput
The vector with which we will multiply.
Assembling using Dohrmann algorithm. Sub structure.
Contains the TPZTimeTemp class which takes times.
static void OpenWrite(const std::string &fileName, streamType=binary)
Contains definitions to LOGPZ_DEBUG, LOGPZ_INFO, LOGPZ_WARN, LOGPZ_ERROR and LOGPZ_FATAL, and the implementation of the inline InitializePZLOG(string) function using log4cxx library or not. It must to be called out of "#ifdef LOG4CXX" scope.
int fNumSub
Number of Substructures.
Definition: TPZTimeTemp.h:30
void Write(TPZStream &buf, int withclassid) const override
Packs the object structure in a stream of bytes.
Definition: pzmatrix.cpp:1420
std::vector< TPZDohrThreadMultData< TSubStruct > > mWorkItems
Array of work items.
std::list< TPZDohrThreadMultData< TSubStruct > > fWork
The list of data objects which need to treated by the threads.
TPZTimeTemp tempo
External variable to TPZTimeTemp (to take time)
Definition: TPZTimeTemp.cpp:11
static int Error(const char *msg, const char *msg2=0)
Returns error messages.
Definition: pzmatrix.cpp:1402
Calculate the Times. Utility.
Definition: TPZfTime.h:21
Contains the TPZDohrMatrix class which implements a matrix divided into substructures. Also contains the TPZDohrThreadMultData and TPZDohrThreadMultList structs.
void Read(TPZStream &buf, void *context) override
Unpacks the object structure from a stream of bytes.
void PrepareZ(const TPZFMatrix< TVar > &y, TPZFMatrix< TVar > &z, const TVar beta, const int opt) const
Is an auxiliar method used by MultiplyAdd.
Definition: pzmatrix.cpp:135
TPZAutoPointer< TPZDohrAssembleList< TVar > > fAssemblyStructure
The local contribution to the v2 vector.
This class implements a simple vector storage scheme for a templated class T. Utility.
Definition: pzgeopoint.h:19
Implements sub structure matrices using Dohrman algorithm. Sub Structure.
Implements a matrix divided into substructures. Matrix Sub structure.
Definition: tpzdohrmatrix.h:30
Contains the TPZDohrAssembly class which implements assembling using Dohrmann algorithm.
virtual void MultAddTBB(const TPZFMatrix< TVar > &x, const TPZFMatrix< TVar > &y, TPZFMatrix< TVar > &z, const TVar alpha, const TVar beta, const int opt) const
It computes z = beta * y + alpha * opt(this)*x but z and x can not overlap in memory.
.. . Sub structure
TVar fAlpha
Scalar multiplication factor.
pthread_mutex_t fAccessLock
Mutex which will enable the access protection of the list.
#define PZ_PTHREAD_JOIN(thread, val, fn)
Definition: pz_pthread.h:34
static TPZAutoPointer< TPZSavable > GetAutoPointer(const int64_t &objId)
TVar fAlpha
Scalar multiplication factor.
ParallelAssembleTaskMatrix(const TPZFMatrix< TVar > &x, TVar alpha, TPZAutoPointer< TPZDohrAssembly< TVar > > assembly, TPZAutoPointer< TPZDohrAssembleList< TVar > > &assemblestruct)
Constructor.
void Push(const T object)
Pushes a copy of the object on the stack.
Definition: pzstack.h:80
virtual void Write(const bool val)
Definition: TPZStream.cpp:8
void AddItem(TPZAutoPointer< TPZDohrAssembleItem< TVar > > assembleItem)
Add an item to the list in a thread safe way.
To condense matrix divided in sub structures. Sub Structure.
#define DebugStop()
Returns a message to user put a breakpoint in.
Definition: pzerror.h:20
int fNumThreads
Number of threads that will be used during the matrix vector multiplication.
Definition: tpzdohrmatrix.h:41
Contains the TPZParallelEnviroment class which store the parallel enviroment variables.
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Definition: pzlog.h:87
void parallel_for(int n, body_t &obj)
Definition: pzparallel.h:24
To assembling one item using Dohrmann algorithm. Sub structure.
int64_t Rows() const
Returns number of rows.
Definition: pzmatrix.h:803
string res
Definition: test.py:151
List of items to assembling using Dohrmann algorithm.
double ReturnTimeDouble()
When called, returns the time since the creation of the object in a double.
Definition: TPZfTime.cpp:35
void Read(TPZStream &buf, void *context) override
Unpacks the object structure from a stream of bytes.
Definition: pzmatrix.cpp:1413
TPZAutoPointer< TPZDohrAssembly< TVar > > fAssembly
The data structure which defines the assemble destinations.
void AddInternalSolution(TPZFMatrix< TVar > &solution)
Add the solution corresponding to the internal residual.
Contains the TPZfTime class which calculates times.
virtual void MultAdd(const TPZFMatrix< TVar > &x, const TPZFMatrix< TVar > &y, TPZFMatrix< TVar > &z, const TVar alpha, const TVar beta, const int opt) const override
TPZStack< REAL > fMultiply
Time to Multiply for each iteration.
Definition: TPZTimeTemp.h:59
Full matrix class. Matrix.
Definition: pzfmatrix.h:32
int Redim(const int64_t newRows, const int64_t newCols) override
Redimension a matrix and ZERO your elements.
Definition: pzfmatrix.h:616
const TPZFMatrix< TVar > * fInput
The vector with which we will multiply.
static void WriteToFile(const TPZSavable *)
TPZDohrThreadMultData< TSubStruct > PopItem()
Interface to pop an item in a thread safe way.
TPZAutoPointer< TSubStruct > fSub
TPZParallelEnviroment pzenviroment
#define PZ_PTHREAD_CREATE(thread, attr, routine, args, fn)
Definition: pz_pthread.h:31
void Write(TPZStream &buf, int withclassid) const override
Packs the object structure in a stream of bytes.
int64_t Cols() const
Returns number of cols.
Definition: pzmatrix.h:809
int ClassId() const override
Routines to send and receive messages.
.. . Sub structure
virtual void Print(std::ostream &out) const
Definition: pzmatrix.h:253
Defines the interface for saving and reading data. Persistency.
Definition: TPZStream.h:50
void Initialize()
Initialize the necessary datastructures.
SubsList fGlobal
Definition: tpzdohrmatrix.h:36
#define SAVEABLE_STR_NOTE(buf, str)
Definition: TPZSavable.h:42
TVar & operator()(const int64_t row, const int64_t col)
The operators check on the bounds if the DEBUG variable is defined.
Definition: pzmatrix.h:867
TPZAutoPointer< TPZDohrAssembly< TVar > > fAssembly
The data structure which defines the assemble destinations.
TPZAutoPointer< TPZDohrAssembleList< TVar > > fAssemblyStructure
The local contribution to the v2 vector.
static void * ThreadWork(void *voidptr)
The procedure which executes the lengthy process.
static void WritePointer(const TPZSavable *obj, TPZStream *stream)
void addWorkItem(TPZDohrThreadMultData< TSubStruct > data)
Add a new work item to the array.
TPZAutoPointer< TPZDohrAssembly< TVar > > fAssembly
Definition: tpzdohrmatrix.h:45
Implements an interface to register a class id and a restore function. Persistence.
Definition: TPZSavable.h:150
#define SAVEABLE_SKIP_NOTE(buf)
Definition: TPZSavable.h:43
virtual void Read(bool &val)
Definition: TPZStream.cpp:91
Root matrix class (abstract). Matrix.
Definition: pzmatrix.h:60
This class implements a reference counter mechanism to administer a dynamically allocated object...