// This puts the special HopFuncs into the MsgDigest. Furthermore, the // Erefs to which they point are the originating Eref instance on the // remote node. This Eref will then invoke its own send call to complete // the message transfer. void Element::putOffNodeTargetsInDigest( unsigned int srcNum, vector< vector< bool > >& targetNodes ) // targetNodes[srcDataId][node] { if ( msgBinding_[ srcNum ].size() == 0 ) return; const MsgFuncBinding& mfb = msgBinding_[ srcNum ][0]; const Msg* msg = Msg::getMsg( mfb.mid ); const OpFunc* func; if ( msg->e1() == this ) { func = msg->e2()->cinfo()->getOpFunc( mfb.fid ); } else { func = msg->e1()->cinfo()->getOpFunc( mfb.fid ); } assert( func ); // How do I eventually destroy these? const OpFunc* hop = func->makeHopFunc( srcNum ); for ( unsigned int i = 0; i < numData(); ++i ) { vector< Eref > tgts; for ( unsigned int j = 0; j < Shell::numNodes(); ++j ) { if ( targetNodes[i][j] ) tgts.push_back( Eref( this, i, j ) ); // This is a hack. I encode the target node # in the FieldIndex // and the originating Eref in the remainder of the Eref. // The HopFunc has to extract both these things to push into // the correct SendBuffer. } if ( tgts.size() > 0 ) { vector< MsgDigest >& md = msgDigest_[ msgBinding_.size() * i + srcNum ]; md.push_back( MsgDigest( hop, tgts ) ); } } }
unsigned int LocalDataElement::getNumOnNode( unsigned int node ) const { unsigned int lastUsedNode = numData_ / numPerNode_; if ( lastUsedNode > node ) return numPerNode_; if ( lastUsedNode == node ) return numData() - node * numPerNode_; return 0; }
void Element::digestMessages() { bool report = 0; // for debugging msgDigest_.clear(); msgDigest_.resize( msgBinding_.size() * numData() ); vector< bool > temp( Shell::numNodes(), false ); vector< vector< bool > > targetNodes( numData(), temp ); // targetNodes[srcDataId][node]. The idea is that if any dataEntry has // a target off-node, it should flag the entry here so that it can // send the message request to the proxy on that node. for ( unsigned int i = 0; i < msgBinding_.size(); ++i ) { // Go through and identify functions with the same ptr. vector< FuncOrder > fo = putFuncsInOrder( this, msgBinding_[i] ); for ( vector< FuncOrder >::const_iterator k = fo.begin(); k != fo.end(); ++k ) { const MsgFuncBinding& mfb = msgBinding_[i][ k->index() ]; putTargetsInDigest( i, mfb, *k, targetNodes ); } if ( Shell::numNodes() > 1 ) { if ( report ) { unsigned int numPre = findNumDigest( msgDigest_, msgBinding_.size(), numData(), i ); putOffNodeTargetsInDigest( i, targetNodes ); unsigned int numPost = findNumDigest( msgDigest_, msgBinding_.size(), numData(), i ); cout << "\nfor Element " << name_; cout << ", Func: " << i << ", numFunc = " << fo.size() << ", numPre= " << numPre << ", numPost= " << numPost << endl; for ( unsigned int j = 0; j < numData(); ++j ) { cout << endl << j << " "; for ( unsigned int node = 0; node < Shell::numNodes(); ++node) { cout << (int)targetNodes[j][node]; } } cout << endl; } else { putOffNodeTargetsInDigest( i, targetNodes ); } } } }
void Element::printMsgDigest( unsigned int srcIndex, unsigned int dataId ) const { unsigned int numSrcMsgs = msgBinding_.size(); unsigned int start = 0; unsigned int end = numData(); if ( dataId < numData() ) { start = dataId; end = dataId + 1; } for (unsigned int i = start; i < end; ++i ) { cout << i << ": "; const vector< MsgDigest> & md = msgDigest_[numSrcMsgs * i + srcIndex]; for ( unsigned int j = 0; j < md.size(); ++j ) { cout << j << ": "; for ( unsigned int k = 0; k < md[j].targets.size(); ++k ) { cout << " " << md[j].targets[k].dataIndex() << "," << md[j].targets[k].fieldIndex(); } } cout << endl; } }