25 #define fei_file "fei_NodeCommMgr.cpp"
31 sharedNodesAllocated_(false),
32 sharedNodeOwnership_(sharedNodeOwnership),
36 sharedNodeSubdomains(),
37 trivialSubdomainList(1),
41 remoteSharingProcs_(),
43 nodesPerSharingProc_(),
50 initCompleteCalled_(false),
51 probStruc(problemStructure)
82 if (index < 0)
return(1);
123 if (sharedIndex < 0)
return(0);
131 if (index == -2)
return(-2);
139 std::vector<int> localMax(2, 0), globalMax(2, 0);
143 if (numFlds > localMax[0]) localMax[0] = numFlds;
146 if (numBlks > localMax[1]) localMax[1] = numBlks;
150 if (err != 0)
return(err);
152 maxFields = globalMax[0];
153 maxBlocks = globalMax[1];
161 std::vector<int> localMax(3, 0), globalMax(3, 0);
165 if (numFlds > localMax[0]) localMax[0] = numFlds;
168 if (numBlks > localMax[1]) localMax[1] = numBlks;
171 if (numShrd > localMax[2]) localMax[2] = numShrd;
175 if (err != 0)
return(err);
199 std::vector<int>::iterator
216 std::vector<int>::iterator
239 int* msgPtr = &message[0];
242 for(
int j=0; j<numNodes; j++) {
244 if (nIndex < 0)
return(-1);
247 int nodeNum = msgPtr[numNodes+offset++];
248 int numFields = msgPtr[numNodes+offset++];
249 int numBlocks = msgPtr[numNodes+offset++];
250 int numSubdomains = msgPtr[numNodes+offset++];
256 for(
int fld=0; fld<numFields; fld++) {
257 int fieldID = msgPtr[numNodes+offset++];
258 int eqnNum = msgPtr[numNodes+offset++];
263 for(
int blk=0; blk<numBlocks; blk++) {
272 for(
int sd=0; sd<numSubdomains; sd++) {
274 msgPtr[numNodes+offset++];
312 #endif //#ifndef FEI_SER
319 int proc,
int numNodes,
int len)
356 if (index < 0)
continue;
358 if (nodeCounter >= numNodes) {
360 <<
" nodeCounter >= numNodes." <<
FEI_ENDL;
375 data[numNodes+offset++] = nodeNum;
376 data[numNodes+offset++] = numFields;
377 data[numNodes+offset++] = numBlocks;
378 data[numNodes+offset++] = subdomains.size();
380 data[numNodes+offset++] = blkEqnNumber;
382 for(
int j=0; j<numFields; j++) {
383 data[numNodes+offset++] = fieldIDsPtr[j];
390 data[numNodes+offset++] = fieldEqnNums[j];
393 for(
int kk=0; kk<numBlocks; kk++) {
395 data[numNodes+offset++] = blkID;
398 for(
unsigned k=0; k<subdomains.size(); k++) {
399 data[numNodes+offset++] = subdomains[k];
406 int proc,
int numNodes,
int len)
435 if (thisProc != proc)
continue;
437 if (nodeCounter >= numNodes) {
439 <<
" nodeCounter >= numNodes: " << numNodes <<
FEI_ENDL;
451 data[numNodes+offset++] = (lindex >= 0) ? 1 : 0;
452 data[numNodes+offset++] = (
GlobalID)numFields;
453 data[numNodes+offset++] = (
GlobalID)numBlocks;
456 for(
int j=0; j<numFields; j++) {
462 data[numNodes+offset++] = (
GlobalID)fieldIDsPtr[j];
465 for(
int k=0; k<numBlocks; k++) {
478 std::vector<int>& procs)
488 int len = itemsPerProc.size();
490 for(
int i=0; i<len; i++) {
491 if (itemsPerProc[i] > 0) numProcs++;
494 procs.resize(numProcs);
498 for(
int i=0; i<len; i++) {
499 if (itemsPerProc[i] > 0) procs[offset++] = i;
517 const int*
const* procs,
527 for(
int i=0; i<numNodes; i++) {
528 int insertPoint = -1;
539 if (err != 0)
return(err);
543 catch(std::runtime_error& exc) {
568 if (err != 0)
return(-1);
594 if (err != 0)
return(err);
607 std::vector<int>::iterator sh_iter =
608 std::lower_bound(shProcs.begin(), shProcs.end(),
localProc_);
609 if (sh_iter == shProcs.end() ||
localProc_ != *sh_iter) {
613 int proc = shProcs[0];
638 if (err != 0)
return(err);
645 if (err != 0)
return(-1);
657 #define _feiFunc_ "NodeCommMgr::checkSharedNodeInfo"
677 std::vector<int> globalOwnerProcs, globalSharingProcs;
678 std::vector<int> recvOwnerLengths, recvSharingLengths;
680 std::vector<int> globalNodesPerOwnerProcs, globalNodesPerSharingProcs;
681 std::vector<int> recvNodesPerOwnerLengths, recvNodesPerSharingLengths;
687 recvOwnerLengths, globalOwnerProcs) );
690 recvNodesPerOwnerLengths,
691 globalNodesPerOwnerProcs) );
694 recvSharingLengths, globalSharingProcs) );
697 recvNodesPerSharingLengths,
698 globalNodesPerSharingProcs) );
703 globalOwnerProcs, globalNodesPerOwnerProcs,
710 globalSharingProcs, globalNodesPerSharingProcs,
723 std::vector<int>& globalRemoteProcs,
724 std::vector<int>& globalNodesPerRemoteProc,
725 std::vector<int>& globalRemoteProcLengths,
726 std::vector<int>& nodesPerRemoteProc,
727 std::vector<int>& remoteProcs)
732 int length = globalRemoteProcLengths[i];
734 if (i==
localProc_) { offset += length;
continue; }
736 for(
int j=0; j<length; j++) {
737 if (globalRemoteProcs[offset+j] ==
localProc_) {
739 int numShared = globalNodesPerRemoteProc[offset+j];
746 <<
") doesn't share nodes with proc " << i <<
" but proc " << i
753 int numWeThinkWeShare = nodesPerRemoteProc[index];
754 if (numWeThinkWeShare != numShared) {
756 <<
" ERROR. Local proc (" <<
localProc_ <<
") thinks it shares "
757 << numWeThinkWeShare <<
" nodes with proc " << i <<
", but proc "
758 << i <<
" thinks it shares " << numShared <<
" nodes with proc "
792 int proc = shProcs[0];
797 if (err == -2)
return(err);
807 std::vector<GlobalID> allRemoteNodeIDs;
808 std::vector<int> numPerProc;
811 if (err != 0)
return(-1);
822 for(
unsigned i=0; i<numPerProc.size(); i++) {
823 for(
int j=0; j<numPerProc[i]; j++) {
828 GlobalID nodeID = allRemoteNodeIDs[offset++];
832 if (index < 0)
continue;
844 if (err != 0)
return(-1);
850 offset = allRemoteNodeIDs.size()-1;
851 for(
int i=(
int)numPerProc.size()-1; i>=0; i--) {
852 for(
int j=0; j<numPerProc[i]; j++) {
853 GlobalID nodeID = allRemoteNodeIDs[offset--];
856 if (index < 0)
continue;
878 std::vector<int> localNodesPerProc(
numProcs_, 0);
879 std::vector<int> remoteNodesPerProc(
numProcs_, 0);
889 remoteNodesPerProc[proc]++;
893 for(
unsigned j=0; j<shProcs.size(); j++) {
894 int sproc = shProcs[j];
897 localNodesPerProc[sproc]++;
906 if (err != 0)
return(err);
909 if (err != 0)
return(err);
918 if (remoteNodesPerProc[i] > 0)
924 if (localNodesPerProc[i] > 0)
940 int maxFields, maxBlocks;
948 int len = 4 + maxFields + maxBlocks;
955 if (numRecvProcs > 0) {
956 recvData =
new GlobalID*[numRecvProcs];
962 int numRcvStarted = 0;
965 recvData[i] =
new GlobalID[numRecvNodes*(len+1)];
966 MPI_Irecv(recvData[i], numRecvNodes*(len+1),
967 fei::mpiTraits<GlobalID>::mpi_type(),
979 std::vector<GlobalID> sendData(numSendNodes*(len+1), 0);
982 numSendNodes, numSendNodes*len);
984 MPI_Send(&sendData[0], sendData.size(),
985 fei::mpiTraits<GlobalID>::mpi_type(),
990 int numCompleted = 0;
994 MPI_Wait(&recvDataReqs[index], &status);
996 int remoteProc = status.MPI_SOURCE;
1001 for(
int j=0; j<numNodes; j++) {
1004 fei::console_out() <<
"NodeCommMgr::exchangeSharedRemote...: error, unknown nodeID "
1005 << (int)recvData[index][j] <<
", " << j
1006 <<
"th node recvd from proc "
1008 <<
". Probably a communication mis-match, we expected "
1010 <<
" nodes from that proc, but recvd less than that." <<
FEI_ENDL;
1014 int residesRemotely = (int)recvData[index][numNodes+offset++];
1016 if (residesRemotely) {
1018 std::vector<int>::iterator sn_iter =
1019 std::lower_bound(snSubd.begin(), snSubd.end(), remoteProc);
1020 if (sn_iter == snSubd.end() || remoteProc != *sn_iter) {
1021 snSubd.insert(sn_iter, remoteProc);
1024 int numFields = (int)recvData[index][numNodes+offset++];
1025 int numBlocks = (int)recvData[index][numNodes+offset++];
1027 setNumNodalDOF((
int)recvData[index][numNodes+offset++]);
1029 for(
int fld=0; fld<numFields; fld++) {
1030 int fieldID = (int)recvData[index][numNodes+offset++];
1035 for(
int blk=0; blk<numBlocks; blk++) {
1045 if (numRcvStarted != numCompleted) {
1046 fei::console_out() <<
"NodeCommMgr::exchangeSharedRemote...: recv-send mismatch;"
1047 <<
" numRcvStarted: " << numRcvStarted <<
", numCompleted: "
1052 for(i=0; i<numRecvProcs; i++) {
1053 delete [] recvData[i];
1057 delete [] recvDataReqs;
1059 #endif //#ifndef FEI_SER
1066 std::vector<std::vector<int>*>& procTable,
1074 std::vector<int>& row_index = *(procTable[index]);
1076 std::vector<int>::iterator r_iter =
1077 std::lower_bound(row_index.begin(), row_index.end(), procs[i]);
1078 if (r_iter == row_index.end() || procs[i] != *r_iter) {
1079 row_index.insert(r_iter, procs[i]);
NodeDescriptor ** sharedNodes_
int GlobalSum(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
int createProcList(std::vector< int > &itemsPerProc, std::vector< int > &procs)
size_t getNumBlocks() const
int sortedListInsert(const T &item, std::vector< T > &list)
void setBlkEqnNumber(int blkEqn)
std::vector< int > trivialSubdomainList
std::vector< GlobalID > sharedNodeIDs
int Allgatherv(MPI_Comm comm, std::vector< T > &sendbuf, std::vector< int > &recvLengths, std::vector< T > &recvbuf)
int adjustSharedOwnership()
int addSharedNodes(const GlobalID *nodeIDs, int numNodes, const int *const *procs, const int *numProcs)
int getNumNodalDOF() const
int getBlockID(unsigned index) const
const int * getFieldIDList() const
std::vector< int > nodesPerOwnerProc_
std::vector< GlobalID > localNodeIDs
std::vector< int > & getSendProcs()
const int * getFieldEqnNumbers() const
void Barrier(MPI_Comm comm)
void setFieldEqnNumber(int fieldID, int eqn)
std::vector< int > sharedNodeNumbers
void addBlockIndex(unsigned blk_idx)
int getSharedNodeIndex(GlobalID nodeID)
int allocateNodeDescriptorPtrs(NodeDatabase &nodeDB)
const SNL_FEI_Structure & probStruc
int initComplete(NodeDatabase &nodeDB, bool safetyCheck)
std::vector< int > nodesPerSharingProc_
std::vector< GlobalID > remoteNodeIDs
int getSharedNodeIndex_num(int nodeNumber)
int binarySearch(const T &item, const T *list, int len)
NodeCommMgr(MPI_Comm comm, const SNL_FEI_Structure &problemStructure, int sharedNodeOwnership=STRICTLY_LOW_PROC)
int checkSharedNodeInfo()
int getGlobalMaxFieldsBlocksSubdomains()
std::vector< int > remoteOwnerProcs_
std::vector< std::vector< int > > sharedNodeSubdomains
void setNodeNumbersArray()
int storeNodeProcs(int index, std::vector< std::vector< int > * > &procTable, const int *procs, int numProcs)
std::vector< int > remoteSharingProcs_
int getSendMessage(int destProc, std::vector< int > &message)
std::vector< std::vector< int > * > sharingProcs_
GlobalID getGlobalNodeID() const
void setNumNodalDOF(int dof)
int informLocal(const NodeDescriptor &node)
int exchange(MPI_Comm comm, MessageHandler< T > *msgHandler)
void packLocalNodesAndData(int *data, int proc, int numNodes, int len)
int getBlkEqnNumber() const
void packRemoteNodesAndData(GlobalID *data, int proc, int numNodes, int len)
int getSharedNodeNumSubdomains(GlobalID nodeID)
void setNodeNumber(int nn)
std::vector< int > & getRecvProcs()
std::ostream & console_out()
int GlobalMax(MPI_Comm comm, std::vector< T > &local, std::vector< T > &global)
const std::vector< unsigned > & getBlockIndexList() const
bool sharedNodesAllocated_
int getGlobalMaxFieldsBlocks(int &maxFields, int &maxBlocks)
int localProc(MPI_Comm comm)
int checkCommArrays(const char *whichCheck, std::vector< int > &globalRemoteProcs, std::vector< int > &globalNodesPerRemoteProc, std::vector< int > &globalRemoteProcLengths, std::vector< int > &nodesPerRemoteProc, std::vector< int > &remoteProcs)
int exchangeSharedRemoteFieldsBlks()
int getSendMessageLength(int destProc, int &messageLength)
int getNodeWithID(GlobalID nodeID, const NodeDescriptor *&node) const
void setOwnerProc(int proc)
void addField(int fieldID)
int processRecvMessage(int srcProc, std::vector< int > &message)
int getNodeNumber() const
int numProcs(MPI_Comm comm)
std::vector< int > * getSharedNodeSubdomainList(GlobalID nodeID)
int getIndexOfBlock(GlobalID blockID) const