/* will delete those dofmanagers, that were sent to remote partition and are locally owned here * so they are no longer necessary (those with state equal to DM_Remote and DM_SharedMerge) * This will update domain DofManager list as well as global dmanMap and physically deletes the remote dofManager */ void LoadBalancer :: deleteRemoteDofManagers(Domain *d) { int i, ndofman = d->giveNumberOfDofManagers(); //LoadBalancer* lb = this->giveLoadBalancer(); LoadBalancer :: DofManMode dmode; DofManager *dman; int myrank = d->giveEngngModel()->giveRank(); DomainTransactionManager *dtm = d->giveTransactionManager(); // loop over local nodes for ( i = 1; i <= ndofman; i++ ) { dmode = this->giveDofManState(i); if ( ( dmode == LoadBalancer :: DM_Remote ) ) { // positive candidate found dtm->addTransaction(DomainTransactionManager :: DTT_Remove, DomainTransactionManager :: DCT_DofManager, d->giveDofManager(i)->giveGlobalNumber(), NULL); // dmanMap.erase (d->giveDofManager (i)->giveGlobalNumber()); //dman = dofManagerList->unlink (i); //delete dman; } else if ( ( dmode == LoadBalancer :: DM_NULL ) ) { // positive candidate found; we delete all null dof managers // they will be created by nonlocalmatwtp if necessary. // potentially, they can be reused, but this will make the code too complex dtm->addTransaction(DomainTransactionManager :: DTT_Remove, DomainTransactionManager :: DCT_DofManager, d->giveDofManager(i)->giveGlobalNumber(), NULL); } else if ( dmode == LoadBalancer :: DM_Shared ) { dman = d->giveDofManager(i); dman->setPartitionList( this->giveDofManPartitions(i) ); dman->setParallelMode(DofManager_shared); if ( !dman->givePartitionList()->findFirstIndexOf(myrank) ) { dtm->addTransaction(DomainTransactionManager :: DTT_Remove, DomainTransactionManager :: DCT_DofManager, d->giveDofManager(i)->giveGlobalNumber(), NULL); //dmanMap.erase (this->giveDofManager (i)->giveGlobalNumber()); //dman = dofManagerList->unlink (i); //delete dman; } } else if ( dmode == LoadBalancer :: DM_Local ) { IntArray _empty(0); dman = d->giveDofManager(i); dman->setPartitionList(& _empty); dman->setParallelMode(DofManager_local); } else { OOFEM_ERROR("Domain::deleteRemoteDofManagers: unknown dmode encountered"); } } }
int NonlocalMaterialWTP :: unpackRemoteElements(Domain *d, ProcessCommunicator &pc) { int myrank = d->giveEngngModel()->giveRank(); int iproc = pc.giveRank(); std :: string _type; DofManager *dofman; IntArray _partitions; if ( iproc == myrank ) { return 1; // skip local partition } // query process communicator to use ProcessCommunicatorBuff *pcbuff = pc.giveProcessCommunicatorBuff(); ProcessCommDataStream pcDataStream(pcbuff); // unpack dofman data do { pcbuff->unpackString(_type); if ( _type.size() == 0 ) { break; } dofman = classFactory.createDofManager(_type.c_str(), 0, d); dofman->restoreContext(& pcDataStream, CM_Definition | CM_State | CM_UnknownDictState); dofman->setParallelMode(DofManager_null); if ( d->dofmanGlobal2Local( dofman->giveGlobalNumber() ) ) { // record already exist delete dofman; } else { d->giveTransactionManager()->addDofManTransaction(DomainTransactionManager :: DTT_ADD, dofman->giveGlobalNumber(), dofman); } } while ( 1 ); // unpack element data Element *elem; _partitions.resize(1); _partitions.at(1) = iproc; do { pcbuff->unpackString(_type); if ( _type.size() == 0 ) { break; } elem = classFactory.createElement(_type.c_str(), 0, d); elem->restoreContext(& pcDataStream, CM_Definition | CM_State); elem->setParallelMode(Element_remote); elem->setPartitionList(_partitions); d->giveTransactionManager()->addElementTransaction(DomainTransactionManager :: DTT_ADD, elem->giveGlobalNumber(), elem); } while ( 1 ); return 1; }
int LoadBalancer :: unpackMigratingData(Domain *d, ProcessCommunicator &pc) { // create temp space for dofManagers and elements // merging should be made by domain ? // maps of new dofmanagers and elements indexed by global number // we can put local dofManagers and elements into maps (should be done before unpacking) // int nproc=this->giveEngngModel()->giveNumberOfProcesses(); int myrank = d->giveEngngModel()->giveRank(); int iproc = pc.giveRank(); int _mode, _globnum, _type; bool _newentry; classType _etype; IntArray _partitions, local_partitions; //LoadBalancer::DofManMode dmode; DofManager *dofman; DomainTransactionManager *dtm = d->giveTransactionManager(); // ************************************************** // Unpack migrating data to remote partition // ************************************************** if ( iproc == myrank ) { return 1; // skip local partition } // query process communicator to use ProcessCommunicatorBuff *pcbuff = pc.giveProcessCommunicatorBuff(); ProcessCommDataStream pcDataStream(pcbuff); pcbuff->unpackInt(_type); // unpack dofman data while ( _type != LOADBALANCER_END_DATA ) { _etype = ( classType ) _type; pcbuff->unpackInt(_mode); switch ( _mode ) { case LoadBalancer :: DM_Remote: // receiving new local dofManager pcbuff->unpackInt(_globnum); /* * _newentry = false; * if ( ( dofman = dtm->giveDofManager(_globnum) ) == NULL ) { * // data not available -> create a new one * _newentry = true; * dofman = CreateUsrDefDofManagerOfType(_etype, 0, d); * } */ _newentry = true; dofman = CreateUsrDefDofManagerOfType(_etype, 0, d); dofman->setGlobalNumber(_globnum); // unpack dofman state (this is the local dofman, not available on remote) dofman->restoreContext(& pcDataStream, CM_Definition | CM_DefinitionGlobal | CM_State | CM_UnknownDictState); // unpack list of new partitions pcbuff->unpackIntArray(_partitions); dofman->setPartitionList(& _partitions); dofman->setParallelMode(DofManager_local); // add transaction if new entry allocated; otherwise existing one has been modified via returned dofman if ( _newentry ) { dtm->addTransaction(DomainTransactionManager :: DTT_ADD, DomainTransactionManager :: DCT_DofManager, _globnum, dofman); } //dmanMap[_globnum] = dofman; break; case LoadBalancer :: DM_Shared: // receiving new shared dofManager, that was local on sending partition // should be received only once (from partition where was local) pcbuff->unpackInt(_globnum); /* * _newentry = false; * if ( ( dofman = dtm->giveDofManager(_globnum) ) == NULL ) { * // data not available -> mode should be SharedUpdate * _newentry = true; * dofman = CreateUsrDefDofManagerOfType(_etype, 0, d); * } */ _newentry = true; dofman = CreateUsrDefDofManagerOfType(_etype, 0, d); dofman->setGlobalNumber(_globnum); // unpack dofman state (this is the local dofman, not available on remote) dofman->restoreContext(& pcDataStream, CM_Definition | CM_DefinitionGlobal | CM_State | CM_UnknownDictState); // unpack list of new partitions pcbuff->unpackIntArray(_partitions); dofman->setPartitionList(& _partitions); dofman->setParallelMode(DofManager_shared); #ifdef __VERBOSE_PARALLEL fprintf(stderr, "[%d] received Shared new dofman [%d]\n", myrank, _globnum); #endif // add transaction if new entry allocated; otherwise existing one has been modified via returned dofman if ( _newentry ) { dtm->addTransaction(DomainTransactionManager :: DTT_ADD, DomainTransactionManager :: DCT_DofManager, _globnum, dofman); } //dmanMap[_globnum] = dofman; break; default: OOFEM_ERROR2("LoadBalancer::unpackMigratingData: unexpected dof manager type (%d)", _type); } // get next type record pcbuff->unpackInt(_type); } ; // while (_type != LOADBALANCER_END_DATA); // unpack element data Element *elem; int nrecv = 0; do { pcbuff->unpackInt(_type); if ( _type == LOADBALANCER_END_DATA ) { break; } _etype = ( classType ) _type; elem = CreateUsrDefElementOfType(_etype, 0, d); elem->restoreContext(& pcDataStream, CM_Definition | CM_State); elem->initForNewStep(); dtm->addTransaction(DomainTransactionManager :: DTT_ADD, DomainTransactionManager :: DCT_Element, elem->giveGlobalNumber(), elem); nrecv++; //recvElemList.push_back(elem); } while ( 1 ); OOFEM_LOG_RELEVANT("[%d] LoadBalancer:: receiving %d migrating elements from %d\n", myrank, nrecv, iproc); return 1; }