38 static LoggerPtr logger(Logger::getLogger(
"pz.strmatrix.TPZStructMatrixTBB"));
39 static LoggerPtr loggerel(Logger::getLogger(
"pz.strmatrix.element"));
40 static LoggerPtr loggerel2(Logger::getLogger(
"pz.strmatrix.elementinterface"));
41 static LoggerPtr loggerelmat(Logger::getLogger(
"pz.strmatrix.elementmat"));
42 static LoggerPtr loggerCheck(Logger::getLogger(
"pz.strmatrix.checkconsistency"));
45 #ifdef CHECKCONSISTENCY 53 static RunStatsTable stat_ass_graph_tbb(
"-ass_graph_tbb",
"Run statistics table for the graph creation, coloring and tbb::flow::graph TPZStructMatrixTBB.");
58 this->fFlowGraph = NULL;
67 this->fFlowGraph =
new TPZFlowGraph(
this,onlyrhs);
74 this->fFlowGraph =
new TPZFlowGraph(
this, onlyrhs);
78 TPZStructMatrixTBB::TPZStructMatrixTBB(
const TPZStructMatrixTBB ©) :
TPZStructMatrixBase(copy)
81 fFlowGraph =
new TPZFlowGraph(*copy.fFlowGraph);
87 TPZStructMatrixTBB::~TPZStructMatrixTBB()
97 std::cout <<
"TPZStructMatrixTBB::Create should never be called\n";
101 TPZStructMatrixTBB *TPZStructMatrixTBB::Clone() {
102 return new TPZStructMatrixTBB(*
this);
114 if (stiffness.
Rows() != neqcondense) {
119 this->MultiThread_Assemble(stiffness,rhsloc,guiInterface);
124 this->MultiThread_Assemble(stiffness,rhs,guiInterface);
136 if(rhs.
Rows() != neqexpand ||
Norm(rhs) != 0.)
141 this->MultiThread_Assemble(rhsloc,guiInterface);
146 this->MultiThread_Assemble(rhs,guiInterface);
155 int64_t cols =
MAX(1, rhs.
Cols());
161 if(loggerel->isDebugEnabled())
163 std::stringstream sout;
164 stiff->
Print(
"Stiffness matrix",sout);
165 rhs.
Print(
"Right hand side", sout);
176 this->fFlowGraph->ExecuteGraph(&rhs, &mat);
178 std::cout <<
"To use the tbb flow graph assemble please compile the NeoPZ with USING_TBB." << std::endl;
187 this->fFlowGraph->ExecuteGraph(&rhs);
189 std::cout <<
"To use the tbb flow graph assemble please compile the NeoPZ with USING_TBB." << std::endl;
198 for (
int i = 0 ; i < connectlist.
NElements() ; i++)
200 if (elContribute[connectlist[i]] >= 0){
209 for (
int i = 0 ; i < connectlist.
NElements() ; i++)
211 elContribute[connectlist[i]] = el;
218 for (
int i = 0 ; i < connectlist.
NElements() ; i++)
220 int elBlocked = elContribute[connectlist[i]];
221 if (elBlocked == -1)
continue;
222 int elBlockedIndex = elSeqinv[elBlocked];
223 if (el == -1) el = elBlockedIndex;
224 if (elBlockedIndex < el) el = elBlockedIndex;
235 for (
int i = 0 ; i < connectlist.
NElements() ; i++)
237 int conindex = connectlist[i];
238 if (elContribute[conindex] != elSequence){
241 elContribute[conindex] = -1;
247 int minPassIndex = -1;
248 for (
int i = 0 ; i < connectlist.
NElements() ; i++)
250 int elcont = elContribute[connectlist[i]];
253 passindex = passIndex[elcont];
254 if (minPassIndex == -1) minPassIndex = passindex;
256 if (minPassIndex < passindex) minPassIndex = passindex;
262 void TPZStructMatrixTBB::TPZFlowGraph::ElementColoring()
265 const int64_t nnodes = fCMesh->NConnects();
266 const int64_t nel = fCMesh->ElementVec().
NElements();
270 fFirstElColor.Push(0);
271 felSequenceColor.Resize(nel);
272 felSequenceColor.Fill(-1);
273 felSequenceColorInv.Resize(nel, -1);
274 felSequenceColorInv.Fill(-1);
275 fnextBlocked.Resize(nel);
276 fnextBlocked.Fill(-1);
277 int nelProcessed = 0;
279 int currentPassIndex = 0;
280 while (nelProcessed < fElementOrder.NElements()){
282 int64_t elindex = fElementOrder[currentEl];
284 if(felSequenceColorInv[elindex] == -1)
286 TPZCompEl *cel = fCMesh->ElementVec()[elindex];
294 int minPass =
MinPassIndex(connectlist,elContribute,passIndex);
296 passIndex[elindex] = currentPassIndex;
298 felSequenceColor[nelProcessed] = elindex;
299 felSequenceColorInv[elindex] = nelProcessed;
302 else if (minPass == currentPassIndex){
304 else if (minPass < currentPassIndex){
306 const int el =
WhoBlockedMe(connectlist,elContribute, felSequenceColorInv);
307 if (fnextBlocked[el] == -1) fnextBlocked[el] = nelProcessed;
308 int locindex = felSequenceColor[el];
309 RemoveEl(locindex,fCMesh,elContribute,locindex);
312 passIndex[elindex] = currentPassIndex;
314 felSequenceColor[nelProcessed] = elindex;
315 felSequenceColorInv[elindex] = nelProcessed;
323 if (currentEl == fElementOrder.NElements()){
324 fFirstElColor.Push(nelProcessed);
331 std::ofstream toto(
"../ColorMeshDebug.txt");
332 toto <<
"elSequence\n" << fElementOrder << std::endl;
333 toto <<
"elSequenceColor\n" << felSequenceColor << std::endl;
334 toto <<
"elSequenceColorInv\n" << felSequenceColorInv << std::endl;
335 toto <<
"elBlocked\n" << fnextBlocked << std::endl;
336 toto <<
"elContribute\n" << elContribute << std::endl;
337 toto <<
"fFirstElColor " << fFirstElColor << std::endl;
338 toto <<
"passIndex\n" << passIndex << std::endl;
343 TPZStructMatrixTBB::TPZFlowGraph::TPZFlowGraph(TPZStructMatrixTBB *strmat,
bool onlyrhs)
344 : fCMesh(strmat->
Mesh()), fStruct(strmat), fGlobMatrix(0), fGlobRhs(0), fOnlyRhs(onlyrhs)
346 this->OrderElements();
347 this->ElementColoring();
349 this->CreateGraphRhs();
357 TPZStructMatrixTBB::TPZFlowGraph::~TPZFlowGraph()
361 void TPZStructMatrixTBB::TPZFlowGraph::OrderElements()
363 int numelconnected = 0;
364 int nconnect = fCMesh->ConnectVec().NElements();
368 firstelconnect[0] = 0;
369 for(ic=0; ic<nconnect; ic++) {
370 numelconnected += fCMesh->ConnectVec()[ic].NElConnected();
371 firstelconnect[ic+1] = firstelconnect[ic]+fCMesh->ConnectVec()[ic].NElConnected();
379 for(el=0; el<fCMesh->ElementVec().NElements(); el++) {
380 cel = fCMesh->ElementVec()[el];
386 for(ic=0; ic<nc; ic++) {
387 int cindex = connectlist[ic];
388 elconnect[firstelconnect[cindex]] = el;
389 firstelconnect[cindex]++;
393 firstelconnect[0] = 0;
395 for(ic=0; ic<nconnect; ic++) {
396 firstelconnect[ic+1] = firstelconnect[ic]+fCMesh->ConnectVec()[ic].NElConnected();
399 fElementOrder.
Resize(fCMesh->ElementVec().NElements(),-1);
400 fElementOrder.Fill(-1);
401 TPZVec<int> nodeorder(fCMesh->ConnectVec().NElements(),-1);
402 firstelconnect[0] = 0;
403 for(ic=0; ic<nconnect; ic++) {
404 int seqnum = fCMesh->ConnectVec()[ic].SequenceNumber();
405 if(seqnum >= 0) nodeorder[seqnum] = ic;
414 TPZVec<int> elorderinv(fCMesh->ElementVec().NElements(),-1);
415 for(seq=0; seq<nconnect; seq++) {
417 if(ic == -1)
continue;
418 int firstind = firstelconnect[ic];
419 int lastind = firstelconnect[ic+1];
421 for(ind=firstind; ind<lastind; ind++) {
426 if(elorderinv[el]==-1) elorderinv[el] = elsequence++;
430 for(seq=0;seq<fCMesh->ElementVec().NElements();seq++) {
431 if(elorderinv[seq] == -1)
continue;
432 fElementOrder[elorderinv[seq]] = seq;
435 for(seq=0;seq<fCMesh->ElementVec().NElements();seq++) {
436 if(fElementOrder[seq]==-1)
break;
439 fElementOrder.
Resize(seq);
442 TPZStructMatrixTBB::TPZFlowGraph::TPZFlowGraph(TPZFlowGraph
const ©)
443 : fCMesh(copy.fStruct->
Mesh()), fStruct(copy.fStruct), fGlobMatrix(0), fGlobRhs(0), fOnlyRhs(copy.fOnlyRhs), fFirstElColor(copy.fFirstElColor)
445 this->fnextBlocked = copy.fnextBlocked;
446 this->felSequenceColor = copy.felSequenceColor;
447 this->felSequenceColorInv = copy.felSequenceColorInv;
448 this->fElementOrder = copy.fElementOrder;
450 this->CreateGraphRhs();
458 void TPZStructMatrixTBB::TPZFlowGraph::CreateGraphRhs()
461 int64_t numcolors = fFirstElColor.size()-1;
462 fNodeDest.resize(numcolors);
467 std::set<int64_t> received;
469 while (numcolors>1) {
472 int64_t halfnumcolors = (numcolors / 2) + numcolors%2;
473 for (int64_t i=halfnumcolors; i< numcolors; i++) {
475 if (received.find(i-halfnumcolors) == received.end()) {
477 received.insert(i-halfnumcolors);
478 fNodeDest[i-halfnumcolors] = sumcolors.
size();
480 if (received.find(i) == received.end()) {
483 fNodeDest[i] = sumcolors.
size();
485 std::pair<int64_t, int64_t> temp(i-halfnumcolors,i);
486 sumcolors.
Push(temp);
489 numcolors = halfnumcolors;
491 numcolors = fFirstElColor.size()-1;
492 fNodes.resize(sumcolors.
size());
495 for (int64_t i=0; i<sumcolors.
size(); i++) {
496 TSumTwoColors block(sumcolors[i].
first,sumcolors[i].second,&fRhsFat);
497 fNodes[i] =
new tbb::flow::continue_node<tbb::flow::continue_msg>(fGraph,numreceive[i],block);
499 for (int64_t i = sumcolors.
size()-1; i>0; i--) {
500 int rhsindex = sumcolors[i].first;
501 for (int64_t j=i-1; j>=0; j++) {
502 if (sumcolors[j].
first == rhsindex || sumcolors[j].second == rhsindex) {
503 tbb::flow::make_edge(*fNodes[i], *fNodes[j]);
508 int64_t neq = fCMesh->NEquations();
509 fRhsFat.Redim(neq, numcolors);
515 void TPZStructMatrixTBB::TPZFlowGraph::CreateGraph()
517 int64_t nelem = fCMesh->NElements();
518 int64_t nconnects = fCMesh->NConnects();
519 int64_t numberOfElements=felSequenceColor.NElements();
523 fNodes.resize(numberOfElements);
524 fElMatPointers.Resize(numberOfElements);
525 for (int64_t iel=0; iel<numberOfElements; iel++) {
526 TPZAssembleTask body(iel,
this);
527 fNodes[iel] =
new tbb::flow::continue_node<tbb::flow::continue_msg>(fGraph,1,body);
531 for (int64_t graphindex = 0; graphindex<numberOfElements; graphindex++) {
532 int64_t el = felSequenceColor[graphindex];
539 std::set<int64_t> fromwhere;
540 for (
int ic=0; ic<connects.
size(); ic++) {
541 int64_t c = connects[ic];
542 if (elementloaded[c] != -1) {
543 int64_t elorig = elementloaded[c];
545 if (fromwhere.find(elorig) == fromwhere.end()) {
547 if (logger->isDebugEnabled()) {
548 std::stringstream sout;
549 sout <<
"Adding edge from " << elorig <<
" to " << graphindex;
554 make_edge(*fNodes[elorig], *fNodes[graphindex]);
556 fromwhere.insert(elorig);
560 for (
int ic=0; ic<connects.
size(); ic++) {
561 int64_t c = connects[ic];
562 elementloaded[c] = graphindex;
571 if (fOnlyRhs && matrix != 0) {
574 this->fGlobMatrix =
matrix;
575 this->fGlobRhs = rhs;
578 TPZCalcTask calcTasks(
this);
579 parallel_for(tbb::blocked_range<int64_t>(0, felSequenceColor.size()), calcTasks );
581 fGraph.wait_for_all();
589 this->fGlobRhs = rhs;
590 this->fGlobMatrix = 0;
591 int64_t numcolors = fFirstElColor.size()-1;
592 fGlobRhs->
Redim(this->fGlobRhs->Rows(), numcolors);
594 TAssembleOneColor onecolor(
this);
595 parallel_for(tbb::blocked_range<int64_t>(0, fFirstElColor.size()-1), onecolor );
597 fGraph.wait_for_all();
598 int64_t nr = fRhsFat.Rows();
599 for (int64_t r=0; r<nr; r++) {
600 (*fGlobRhs)(r,0) = fRhsFat(r,0);
604 void TPZStructMatrixTBB::TPZFlowGraph::TAssembleOneColor::operator()(
const tbb::blocked_range<int64_t> &range)
const 606 for(int64_t color = range.begin(); color != range.end(); ++color)
608 TComputeElementRange elrange(fFlowGraph,color);
609 int64_t firstel = fFlowGraph->fFirstElColor[color];
610 int64_t lastel = fFlowGraph->fFirstElColor[color+1];
611 parallel_for(tbb::blocked_range<int64_t>(firstel,lastel),elrange);
613 int64_t node = fFlowGraph->fNodeDest[color];
614 (fFlowGraph->fNodes)[node]->try_put(tbb::flow::continue_msg());
619 void TPZStructMatrixTBB::TPZFlowGraph::TComputeElementRange::operator()(
const tbb::blocked_range<int64_t> &range)
const 625 for (int64_t iel=range.begin(); iel != range.end(); iel++)
628 if (logger->isDebugEnabled()) {
629 std::stringstream sout;
630 sout <<
"Computing element " << iel;
635 std::stringstream sout;
636 sout <<
"Element " << iel <<
" elapsed time ";
641 int element = fFlowGraph->felSequenceColor[iel];
653 ef.ComputeDestinationIndices();
654 fFlowGraph->fStruct->FilterEquations(ef.fSourceIndex,ef.fDestinationIndex);
657 ef.ApplyConstraints();
658 ef.ComputeDestinationIndices();
659 fFlowGraph->fStruct->FilterEquations(ef.fSourceIndex,ef.fDestinationIndex);
664 int64_t nrows = fFlowGraph->fGlobRhs->Rows();
667 if(!ef.HasDependency()) {
669 locrhs.
AddFel(ef.fMat,ef.fSourceIndex,ef.fDestinationIndex);
672 locrhs.AddFel(ef.fConstrMat,ef.fSourceIndex,ef.fDestinationIndex);
681 tbb::flow::continue_msg TPZStructMatrixTBB::TPZFlowGraph::TPZAssembleTask::operator()(
const tbb::flow::continue_msg &msg)
684 if (logger->isDebugEnabled())
686 std::stringstream sout;
687 sout << __PRETTY_FUNCTION__ <<
" Element " << this->fIel;
699 if(fOrigin->fGlobMatrix) {
701 if(!Ek->HasDependency()) {
702 fOrigin->fGlobMatrix->AddKel(Ek->fMat,Ek->fSourceIndex,Ek->fDestinationIndex);
703 fOrigin->fGlobRhs->AddFel(Ef->fMat,Ek->fSourceIndex,Ek->fDestinationIndex);
705 fOrigin->fGlobMatrix->AddKel(Ek->fConstrMat,Ek->fSourceIndex,Ek->fDestinationIndex);
706 fOrigin->fGlobRhs->AddFel(Ef->fConstrMat,Ek->fSourceIndex,Ek->fDestinationIndex);
709 if(!Ef->HasDependency()) {
710 fOrigin->fGlobRhs->AddFel(Ef->fMat,Ef->fSourceIndex,Ef->fDestinationIndex);
712 fOrigin->fGlobRhs->AddFel(Ef->fConstrMat,Ef->fSourceIndex,Ef->fDestinationIndex);
722 return tbb::flow::continue_msg();
725 void TPZStructMatrixTBB::TPZFlowGraph::TPZCalcTask::operator()(
const tbb::blocked_range<int64_t>& range)
const 731 for(
int iel = range.begin(); iel != range.end(); ++iel) {
733 int element = elSequenceColor[iel];
740 TPZAssembleTask
Assemble = tbb::flow::copy_body<TPZAssembleTask,tbb::flow::continue_node<tbb::flow::continue_msg> >(*fFlowGraph->fNodes[element]);
741 if (Assemble.fIel != element) {
744 if (fFlowGraph->fGlobMatrix)
757 if (fFlowGraph->fGlobMatrix)
764 if (fFlowGraph->fGlobMatrix) {
774 if (fFlowGraph->fGlobMatrix) {
787 if (logger->isDebugEnabled())
789 std::stringstream sout;
790 sout << __PRETTY_FUNCTION__ <<
" Element " << element;
794 (fFlowGraph->fNodes)[element]->try_put(tbb::flow::continue_msg());
801 int TPZStructMatrixTBB::ClassId()
const{
805 void TPZStructMatrixTBB::Read(
TPZStream& buf,
void* context) {
812 void TPZStructMatrixTBB::Write(
TPZStream& buf,
int withclassid)
const {
static RunStatsTable ass_stiff("-ass_stiff", "Assemble Stiffness")
Contains a class to record running statistics on CSV tables.
The timer class. Utility.
static int MinPassIndex(TPZStack< int64_t > &connectlist, TPZVec< int > &elContribute, TPZVec< int > &passIndex)
static void RemoveEl(int el, TPZCompMesh *cmesh, TPZVec< int > &elContribute, int elSequence)
Contains TPZAnalysis class which implements the sequence of actions to perform a finite element analy...
void Scatter(const TPZFMatrix< TVar > &vsmall, TPZFMatrix< TVar > &vexpand) const
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.
TPZEquationFilter fEquationFilter
Object which will determine which equations will be assembled.
Timing class. Absolutely copied from GNU time. Take a look at
virtual void BuildConnectList(std::set< int64_t > &indepconnectlist, std::set< int64_t > &depconnectlist)
Builds the list of all connectivities related to the element including the connects pointed to by dep...
Contains declaration of TPZGeoNode class which defines a geometrical node.
int64_t NEquations()
This computes the number of equations associated with non-restrained nodes.
void AddFel(TPZFMatrix< TVar > &rhs, TPZVec< int64_t > &destination)
Performs a right hand side assemblage.
static bool CanAssemble(TPZStack< int64_t > &connectlist, TPZVec< int > &elContribute)
Contains declaration of TPZCompEl class which defines the interface of a computational element...
Templated vector implementation.
Contains the TPZStructMatrixTBB class which responsible for a interface among Matrix and Finite Eleme...
virtual void CalcStiff(TPZElementMatrix &ek, TPZElementMatrix &ef)
Computes the element stifness matrix and right hand side.
Declarates the TPZBlock<REAL>class which implements block matrices.
#define MAX(a, b)
Gets maxime value between a and b.
int ClassId() const override
Define the class id associated with the class.
static TPZSavable * GetInstance(const int64_t &objId)
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object.
TPZManVector< int64_t > fDestinationIndex
void ComputeDestinationIndices()
TPZSkylMatrix< REAL > matrix
static RunStatsTable stat_ass_graph_tbb("-ass_graph_tbb", "Run statistics table for the graph creation, coloring and tbb::flow::graph TPZStructMatrixTBBFlow.")
Contains declaration of TPZElementMatrix struct which associates an element matrix with the coeficien...
static void AssembleColor(int el, TPZStack< int64_t > &connectlist, TPZVec< int > &elContribute)
int64_t size() const
Returns the number of elements of the vector.
virtual void Resize(const int64_t newsize, const T &object)
Resizes the vector object reallocating the necessary storage, copying the existing objects to the new...
Contains declaration of TPZMesh class which defines a geometrical mesh and contains a corresponding l...
void Push(const T object)
Pushes a copy of the object on the stack.
int64_t NActiveEquations() const
Retorna o numero de equacoes ativas do sistema.
void start()
Turns the timer on.
TVar Norm(const TPZFMatrix< TVar > &A)
Returns the norm of the matrix A.
Contains TPZMatrixclass which implements full matrix (using column major representation).
#define DebugStop()
Returns a message to user put a breakpoint in.
TPZCompMesh * Mesh() const override
Access method for the mesh pointer.
virtual void SetNumThreads(int n)
#define LOGPZ_DEBUG(A, B)
Define log for debug info.
Free store vector implementation.
void parallel_for(int n, body_t &obj)
int64_t Rows() const
Returns number of rows.
virtual void Assemble(TPZMatrix< STATE > &mat, TPZFMatrix< STATE > &rhs, TPZAutoPointer< TPZGuiInterface > guiInterface) override
Assemble the global system of equations into the matrix which has already been created.
void Write(TPZStream &buf, int withclassid) const override
Writes this object to the TPZStream buffer. Include the classid if withclassid = true.
int64_t NEqExpand() const
Retorna o numero de equacoes do sistema original.
Implements an interface to check the consistency of two implementations. Utility. ...
TPZManVector< int64_t > fSourceIndex
Contains declaration of TPZCompMesh class which is a repository for computational elements...
int Redim(const int64_t newRows, const int64_t newCols) override
Redimension a matrix and ZERO your elements.
int32_t Hash(std::string str)
This class associates an element matrix with the coeficients of its contribution in the global stiffn...
static RunStatsTable ass_rhs("-ass_rhs", "Assemble Stiffness")
void ApplyConstraints()
Apply the constraints applied to the nodes by transforming the tangent matrix and right hand side...
Contains declaration of TPZSubCompMesh class which implements a group of computational elements as a ...
virtual void CalcResidual(TPZElementMatrix &ef)
Computes the element right hand side.
Implements computational mesh. Computational Mesh.
TPZAdmChunkVector< TPZCompEl * > & ElementVec()
Returns a reference to the element pointers vector.
Contains declaration of TPZInterpolatedElement class which implements computational element of the in...
virtual TPZMatrix< STATE > * Create() override
int64_t Cols() const
Returns number of cols.
virtual void Print(std::ostream &out) const
Defines the interface for saving and reading data. Persistency.
int64_t NElements() const
Returns the number of elements of the vector.
static int WhoBlockedMe(TPZStack< int64_t > &connectlist, TPZVec< int > &elContribute, TPZVec< int > &elSeqinv)
Defines the interface of a computational element. Computational Element.
virtual int HasDependency()
Returns 1 if the element has at least one dependent node. Returns 0 otherwise.
void Read(TPZStream &buf, void *context) override
read objects from the stream
Implements an interface to register a class id and a restore function. Persistence.
Contains TPZSFMatrix class which implements a symmetric full matrix.