void OneToOneMsg::targets( vector< vector< Eref > > & v) const
{
	unsigned int n = e1_->numData();
	v.resize( e1_->numData() );
	if ( e2_->hasFields() ) {
		if ( Eref( e2_, i2_ ).isDataHere() ) {
			assert( i2_ > e2_->localDataStart() );
			unsigned int nf = e2_->numField( i2_ - e2_->localDataStart() ); 
			if ( n > nf )
				n = nf;
			for ( unsigned int i = 0; i < n; ++i )
				v[i].resize( 1, Eref( e2_, i2_, i ) );
		} else { // Don't know target node # of entries, so send all.
			unsigned int start = e1_->localDataStart();
			unsigned int end = start + e1_->numLocalData();
			for ( unsigned int i = start; i < end; ++i ) {
				v[i].resize( 1, Eref( e2_, i2_, i ) );
			}
		}
	} else {
		if ( n > e2_->numData() )
			n = e2_->numData();
		for ( unsigned int i = 0; i < n; ++i ) {
			v[i].resize( 1, Eref( e2_, i ) );
		}
	}
}
Esempio n. 2
0
void ZombieHandler::forall( const OpFunc* f, Element* e, const Qinfo* q,
 	const double* arg, unsigned int argSize, unsigned int numArgs ) const
{ // This should be relevant. But I still have to define threadStart_
	// Find which thread parent is willing to handle
	// I still don't know how to get at the parent DataId. I need it.
	if ( parent_->execThread( q->threadNum(), 0 ) ) {
		// On this thread, figure out which index range we should use.
		// We have start and end, so that is fine.
		// Iterate through the opfunc for all of these.
		if ( numArgs <= 1 ) {
			for( unsigned int i = start_; i != end_; ++i ) {
				f->op( Eref( e, i ), q, arg );
			}
		} else {
			unsigned int argOffset = argSize * start_;
			unsigned int maxOffset = argSize * numArgs;
			for( unsigned int i = start_; i != end_; ++i ) {
				f->op( Eref( e, i ), q, arg + argOffset );
				argOffset += argSize;
				if ( argOffset >= maxOffset )
					argOffset = 0;
			}
		}
	}
}
Eref OneToAllMsg::firstTgt( const Eref& src ) const 
{
	if ( src.element() == e1_ )
		return Eref( e2_, 0 );
	else if ( src.element() == e2_ )
		return Eref( e1_, i1_ );
	return Eref( 0, 0 );
}
Eref SingleMsg::firstTgt( const Eref& src ) const 
{
	if ( src.element() == e1_ )
		return Eref( e2_, i2_, f2_ );
	else if ( src.element() == e2_ )
		return Eref( e1_, i1_ );
	return Eref( 0, 0 );
}
/**
 * This is a little tricky because we might be mapping between
 * data entries and field entries here.
 * May wish also to apply to exec operations.
 * At this point, the effect of trying to go between regular
 * data entries and field entries is undefined.
 */
Eref OneToOneDataIndexMsg::firstTgt( const Eref& src ) const
{
	if ( src.element() == e1_ ) {
		return Eref( e2_, src.dataIndex(), 0 );
	} else if ( src.element() == e2_ ) {
		return Eref( e1_, src.dataIndex() );
	}
	return Eref( 0, 0 );
}
/**
 * This is a little tricky because we might be mapping between
 * data entries and field entries here.
 * May wish also to apply to exec operations.
 * At this point, the effect of trying to go between regular
 * data entries and field entries is undefined.
 */
Eref OneToOneMsg::firstTgt( const Eref& src ) const 
{
	if ( src.element() == e1_ ) {
		if ( e2_->hasFields() )
			return Eref( e2_, i2_, src.dataIndex() );
		else 
			return Eref( e2_, src.dataIndex(), 0 );
	} else if ( src.element() == e2_ ) {
		return Eref( e1_, src.dataIndex() );
	}
	return Eref( 0, 0 );
}
Esempio n. 7
0
// 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 ) );
		}
	}
}
void OneToAllMsg::sources( vector< vector < Eref > >& v ) const
{
	// Same single source for all targets.
	v.clear();
	vector< Eref > temp( 1, Eref( e1_, i1_ ) );
	v.assign( e2_->numData(), temp  );
}
Esempio n. 9
0
Eref SparseMsg::firstTgt( const Eref& src ) const 
{
	if ( matrix_.nEntries() == 0 )
		return Eref( 0, 0 );

	if ( src.element() == e1_ ) {
		const unsigned int* fieldIndex;
		const unsigned int* colIndex;
		unsigned int n = matrix_.getRow( src.dataIndex(),
			&fieldIndex, &colIndex );
		if ( n != 0 ) {
			return Eref( e2_, colIndex[0], fieldIndex[0] );
		}
	} else if ( src.element() == e2_ ) {
		return Eref( e1_, 0 );
	}
	return Eref( 0, 0 );
}
Esempio n. 10
0
void OneToOneDataIndexMsg::targets( vector< vector< Eref > > & v) const
{
	unsigned int n = e1_->numData();
	v.resize( e1_->numData() );
	if ( n > e2_->numData() )
		n = e2_->numData();
	for ( unsigned int i = 0; i < n; ++i ) {
		v[i].resize( 1, Eref( e2_, i ) );
	}
}
Esempio n. 11
0
void ZombieFunction::zombify( Element* orig, const Cinfo* zClass,
					Id ksolve, Id dsolve )
{
	//cout << "ZombieFunction::zombify: " << orig->id().path() << endl;
	if ( orig->cinfo() == zClass )
			return;
	// unsigned int start = orig->localDataStart();
	unsigned int num = orig->numLocalData();
	if ( num == 0 )
		return;
	if ( num > 1 )
		cout << "ZombieFunction::zombify: Warning: ZombieFunction doesn't\n"
				"handle volumes yet. Proceeding without this.\n";

	Function* f = reinterpret_cast< Function *>( Eref( orig, 0 ).data() );
	Function temp = *f;
	orig->zombieSwap( zClass );
	if ( zClass == ZombieFunction::initCinfo() ) { // call SetSolver
		ZombieFunction* zf = reinterpret_cast< ZombieFunction *>(
						Eref( orig, 0 ).data() );
		*zf = *static_cast< ZombieFunction* >(&temp);
		zf->setSolver( ksolve, dsolve );
	} else {
		Function* nf =
					reinterpret_cast< Function *>(Eref( orig, 0 ).data());
		*nf = temp;
	}

	/*
	// We can swap the class because the class data is identical, just
	// the moose expr and process handlers are different.
	if ( orig->cinfo() == ZombieFunction::initCinfo() ) { // unzombify
		orig->replaceCinfo( Function::initCinfo() );
	} else { // zombify
		orig->replaceCinfo( ZombieFunction::initCinfo() );
		ZombieFunction* zf = reinterpret_cast< ZombieFunction *>(
						Eref( orig, 0 ).data() );
		zf->setSolver( ksolve, dsolve );
	}
	*/
}
Esempio n. 12
0
Msg* OneToAllMsg::copy( Id origSrc, Id newSrc, Id newTgt,
			FuncId fid, unsigned int b, unsigned int n ) const
{
	const Element* orig = origSrc();
	if ( n <= 1 ) {
		OneToAllMsg* ret = 0;
		if ( orig == e1() ) {
			ret = new OneToAllMsg( Msg::nextMsgId(), Eref( newSrc(), i1_ ), newTgt() );
			ret->e1()->addMsgAndFunc( ret->mid(), fid, b );
		} else if ( orig == e2() ) {
			ret = new OneToAllMsg( Msg::nextMsgId(), Eref( newTgt(), i1_ ), newSrc() );
			ret->e2()->addMsgAndFunc( ret->mid(), fid, b );
		} else {
			assert( 0 );
		}
		return ret;
	} else {
		// Here we need a SliceMsg which goes from one 2-d array to another.
		cout << "Error: OneToAllMsg::copy: SliceToSliceMsg not yet implemented\n";
		return 0;
	}
}
// We don't permit e1 to have fields at this point.
void OneToOneMsg::sources( vector< vector< Eref > > & v) const
{
	v.resize( 0 );
	unsigned int n = e1_->numData();
	if ( e2_->hasFields() ) {
		if ( Eref( e2_, i2_ ).isDataHere() ) {
			assert( i2_ > e2_->localDataStart() );
			unsigned int nf = e2_->numField( i2_ - e2_->localDataStart() ); 
			if ( n > nf )
				n = nf;
			v.resize( n );
			for ( unsigned int i = 0; i < n; ++i ) {
				v[i].resize( 1, Eref( e1_, i ) );
			}
		}
	} else {
		if ( n > e2_->numData() )
			n = e2_->numData();
		v.resize( e2_->numData() );
		for ( unsigned int i = 0; i < n; ++i ) {
			v[i].resize( 1, Eref( e1_, i ) );
		}
	}
}
Esempio n. 14
0
/**
 * Need to revisit to handle nodes
 */
void OneToAllMsg::exec( const Qinfo* q, const double* arg, FuncId fid ) 
	const
{
	if ( q->src().element() == e1_ ) {
		if ( q->src().dataId == i1_ ) {
			const OpFunc* f = e2_->cinfo()->getOpFunc( fid );
			e2_->dataHandler()->forall( f, e2_, q, arg, 1, 0 );
		}
	} else {
		if ( e1_->dataHandler()->execThread( q->threadNum(), i1_ ) )
		{
			const OpFunc* f = e1_->cinfo()->getOpFunc( fid );
			f->op( Eref( e1_, i1_ ), q, arg );
		}
	}
}
Esempio n. 15
0
void fillErefsFromMatrix( 
		const SparseMatrix< unsigned int >& matrix, 
		vector< vector < Eref > >& v, Element* e1, Element* e2 )
{
	v.clear();
	v.resize( e1->numData() );
	assert( e1->numData() == matrix.nRows() );
	assert( e2->numData() == matrix.nColumns() );
	for ( unsigned int i = 0; i < e1->numData(); ++i ) {
		const unsigned int* entry;
		const unsigned int* colIndex;
		unsigned int num = matrix.getRow( i, &entry, &colIndex );
		v[i].resize( num );
		for ( unsigned int j = 0; j < num; ++j ) {
			v[i][j] = Eref( e2, colIndex[j], entry[j] );
		}
	}
}
Esempio n. 16
0
void HSolveHub::manageCompartments()
{
	const vector< Id >& idlist = integ_->getCompartments();
	vector< Element* > elist;
	idlist2elist( idlist, elist );
	
	const vector< vector< Id > >& externalChannelIds =
		integ_->getExternalChannels();
	vector< Element* > extChanList;
	
	const Finfo* initFinfo = initCompartmentCinfo()->findFinfo( "init" );
	vector< Element* >::const_iterator i;
	for ( i = elist.begin(); i != elist.end(); i++ ) {
		zombify( hub_, *i, compartmentSolveFinfo, compartmentZombieFinfo );
		
		// Compartment receives 2 shared messages from Tick's "process"
		Eref( *i ).dropAll( initFinfo->msg() );
		
		redirectDynamicMessages( *i );
	}
	
	/*
	 * Redirecting dest/shared messages
	 */
	for ( unsigned int ic = 0; ic < elist.size(); ic++ ) {
		// The 'retain' flag at the end is 1: we do not delete the original
		// message to the compartment.
		redirectDestMessages(
			hub_, elist[ ic ],
			hubCompartmentInjectFinfo, compartmentInjectFinfo, 
			ic, compartmentInjectMap_,
			&elist, 0,
			1 );
		
		extChanList.clear();
		idlist2elist( externalChannelIds[ ic ], extChanList );
		redirectDestMessages(
			hub_, elist[ ic ],
			hubCompartmentChannelFinfo, compartmentChannelFinfo, 
			ic, compartmentChannelMap_,
			&elist, &extChanList,
			1 );
	}
}
void OneToAllMsg::targets( vector< vector< Eref > >& v ) const
{
	v.clear();
	v.resize( e1_->numData() );
	v[i1_].resize( 1, Eref( e2_, ALLDATA ) );
}
Esempio n. 18
0
void SingleMsg::sources( vector< vector< Eref > >& v ) const
{
	v.clear();
	v.resize( e2_->numData() );
	v[i2_].resize( 1, Eref( e1_, i1_ ) );
}
Esempio n. 19
0
void SingleMsg::targets( vector< vector< Eref > >& v ) const
{
	v.clear();
	v.resize( e1_->numData() );
	v[i1_].resize( 1, Eref( e2_, i2_, f2_ ) );
}
Esempio n. 20
0
void testBioScan( )
{
	cout << "\nTesting Bioscan" << flush;
	bool success;
	
	Element* n =
		Neutral::create( "Neutral", "n", Element::root()->id(), Id::scratchId() );
	
	/**
	 *  First we test the functions which return the compartments linked to a
	 *  given compartment: adjacent(), and children().
	 *  
	 *  A small tree is created for this:
	 *  
	 *               c0
	 *                L c1
	 *                   L c2
	 *                   L c3
	 *                   L c4
	 *                   L c5
	 *  
	 *  (c0 is the parent of c1. c1 is the parent of c2, c3, c4, c5.)
	 */
	Element* c[ 6 ];
	c[ 0 ] = Neutral::create( "Compartment", "c0", n->id(), Id::scratchId() );
	c[ 1 ] = Neutral::create( "Compartment", "c1", n->id(), Id::scratchId() );
	c[ 2 ] = Neutral::create( "Compartment", "c2", n->id(), Id::scratchId() );
	c[ 3 ] = Neutral::create( "Compartment", "c3", n->id(), Id::scratchId() );
	c[ 4 ] = Neutral::create( "Compartment", "c4", n->id(), Id::scratchId() );
	c[ 5 ] = Neutral::create( "Compartment", "c5", n->id(), Id::scratchId() );
	
	success = Eref( c[ 0 ] ).add( "axial", c[ 1 ], "raxial" );
	ASSERT( success, "Linking compartments" );
	success = Eref( c[ 1 ] ).add( "axial", c[ 2 ], "raxial" );
	ASSERT( success, "Linking compartments" );
	success = Eref( c[ 1 ] ).add( "axial", c[ 3 ], "raxial" );
	ASSERT( success, "Linking compartments" );
	success = Eref( c[ 1 ] ).add( "axial", c[ 4 ], "raxial" );
	ASSERT( success, "Linking compartments" );
	success = Eref( c[ 1 ] ).add( "axial", c[ 5 ], "raxial" );
	ASSERT( success, "Linking compartments" );
	
	vector< Id > found;
	unsigned int nFound;
	
	/** Testing version 1 of BioScan::adjacent.
	 *  It finds all neighbours of given compartment.
	 */
	// Neighbours of c0
	nFound = BioScan::adjacent( c[ 0 ]->id(), found );
	ASSERT( nFound == found.size(), "Finding adjacent compartments" );
	// c1 is adjacent
	ASSERT( nFound == 1, "Finding adjacent compartments" );
	ASSERT( found[ 0 ] == c[ 1 ]->id(), "Finding adjacent compartments" );
	
	// Neighbours of c1
	found.clear();
	nFound = BioScan::adjacent( c[ 1 ]->id(), found );
	ASSERT( nFound == 5, "Finding adjacent compartments" );
	// c0 is adjacent
	success =
		find( found.begin(), found.end(), c[ 0 ]->id() ) != found.end();
	ASSERT( success, "Finding adjacent compartments" );
	// c2 - c5 are adjacent
	for ( int i = 2; i < 6; i++ ) {
		success =
			find( found.begin(), found.end(), c[ i ]->id() ) != found.end();
		ASSERT( success, "Finding adjacent compartments" );
	}
	
	// Neighbours of c2
	found.clear();
	nFound = BioScan::adjacent( c[ 2 ]->id(), found );
	// c1 is adjacent
	ASSERT( nFound == 1, "Finding adjacent compartments" );
	ASSERT( found[ 0 ] == c[ 1 ]->id(), "Finding adjacent compartments" );
	
	/** Testing version 2 of BioScan::adjacent.
	 *  It finds all but one neighbours of given compartment.
	 *  The the second argument to 'adjacent' is the one that is excluded.
	 */
	// Neighbours of c1 (excluding c0)
	found.clear();
	nFound = BioScan::adjacent( c[ 1 ]->id(), c[ 0 ]->id(), found );
	ASSERT( nFound == 4, "Finding adjacent compartments" );
	// c2 - c5 are adjacent
	for ( int i = 2; i < 6; i++ ) {
		success =
			find( found.begin(), found.end(), c[ i ]->id() ) != found.end();
		ASSERT( success, "Finding adjacent compartments" );
	}
	
	// Neighbours of c1 (excluding c2)
	found.clear();
	nFound = BioScan::adjacent( c[ 1 ]->id(), c[ 2 ]->id(), found );
	ASSERT( nFound == 4, "Finding adjacent compartments" );
	// c0 is adjacent
	success =
		find( found.begin(), found.end(), c[ 0 ]->id() ) != found.end();
	ASSERT( success, "Finding adjacent compartments" );
	// c3 - c5 are adjacent
	for ( int i = 3; i < 6; i++ ) {
		success =
			find( found.begin(), found.end(), c[ i ]->id() ) != found.end();
		ASSERT( success, "Finding adjacent compartments" );
	}
	
	// Neighbours of c2 (excluding c1)
	found.clear();
	nFound = BioScan::adjacent( c[ 2 ]->id(), c[ 1 ]->id(), found );
	// None adjacent, if c1 is excluded
	ASSERT( nFound == 0, "Finding adjacent compartments" );
	
	// Neighbours of c2 (excluding c3)
	found.clear();
	nFound = BioScan::adjacent( c[ 2 ]->id(), c[ 3 ]->id(), found );
	// c1 is adjacent, while c3 is not even connected
	ASSERT( nFound == 1, "Finding adjacent compartments" );
	ASSERT( found[ 0 ] == c[ 1 ]->id(), "Finding adjacent compartments" );
	
	/** Testing BioScan::children.
	 *  It finds all compartments which are dests for the "axial" message.
	 */
	// Children of c0
	found.clear();
	nFound = BioScan::children( c[ 0 ]->id(), found );
	ASSERT( nFound == 1, "Finding child compartments" );
	// c1 is a child
	ASSERT( found[ 0 ] == c[ 1 ]->id(), "Finding child compartments" );
	
	// Children of c1
	found.clear();
	nFound = BioScan::children( c[ 1 ]->id(), found );
	ASSERT( nFound == 4, "Finding child compartments" );
	// c2 - c5 are c1's children
	for ( int i = 2; i < 6; i++ ) {
		success =
			find( found.begin(), found.end(), c[ i ]->id() ) != found.end();
		ASSERT( success, "Finding child compartments" );
	}
	
	// Children of c2
	found.clear();
	nFound = BioScan::children( c[ 2 ]->id(), found );
	// c2 has no children
	ASSERT( nFound == 0, "Finding child compartments" );
	
	// Clean up
	set( n, "destroy" );
}
Esempio n. 21
0
Eref Id::eref() const 
{
	return Eref( elements()[ id_ ], 0 );
	// return Eref( elements()[ id_ ], index_ );
}