ObjId OneToOneDataIndexMsg::findOtherEnd( ObjId f ) const
{
	if ( f.element() == e1() )
		return ObjId( e2()->id(), f.dataIndex );
	else if ( f.element() == e2() )
		return ObjId( e1()->id(), f.dataIndex );

	return ObjId( 0, BADINDEX );
}
Esempio n. 2
0
void EndoMesh::setSurround( const Eref& e, ObjId v )
{
	if ( !v.element()->cinfo()->isA( "ChemCompt" ) ) {
		cout << "Warning: 'surround' may only be set to an object of class 'ChemCompt'\n";
		cout << v.path() << " is of class " << v.element()->cinfo()->name() << endl;
		return;
	}
	surround_ = v;
	parent_ = reinterpret_cast< const MeshCompt* >( v.data() );
}
ObjId OneToAllMsg::findOtherEnd( ObjId f ) const
{
	if ( f.element() == e1() ) {
		if ( f.dataIndex == i1_ )
			return ObjId( e2()->id(), 0 );
	} else if ( f.element() == e2() ) {
		return ObjId( e1()->id(), i1_ );
	}
	
	return ObjId( 0, BADINDEX );
}
Esempio n. 4
0
/**
   Populates the vector of event data buffers (vectors), vector of
   event source objects, vector of event source fields and the vector
   of event datasets by querying the messages on InputVariables.
 */
void NSDFWriter::openEventData(const Eref &eref)
{
    if (filehandle_ <= 0){
        return;
    }
    for (unsigned int ii = 0; ii < eventInputs_.size(); ++ii){
        stringstream path;
        path << eref.objId().path() << "/" << "eventInput[" << ii << "]";
        ObjId inputObj = ObjId(path.str());
        Element * el = inputObj.element();
        const DestFinfo * dest = static_cast<const DestFinfo*>(el->cinfo()->findFinfo("input"));
        vector < ObjId > src;
        vector < string > srcFields;
        el->getMsgSourceAndSender(dest->getFid(), src, srcFields);
        if (src.size() > 1){
            cerr << "NSDFWriter::openEventData - only one source can be connected to an eventInput" <<endl;
        } else if (src.size() == 1){
            eventSrcFields_.push_back(srcFields[0]);
            eventSrc_.push_back(src[0].path());
            events_.resize(eventSrc_.size());
            stringstream path;
            path << src[0].path() << "." << srcFields[0];
            hid_t dataSet = getEventDataset(src[0].path(), srcFields[0]);
            eventDatasets_.push_back(dataSet);            
        } else {
            cerr <<"NSDFWriter::openEventData - cannot handle multiple connections at single input." <<endl;
        }
    }
}
Esempio n. 5
0
void Shell::doMove( Id orig, ObjId newParent )
{
	if ( orig == Id() ) {
		cout << "Error: Shell::doMove: Cannot move root Element\n";
		return;
	}

	if ( newParent.element() == 0 ) {
		cout << "Error: Shell::doMove: Cannot move object to null parent \n";
		return;
	}
	if ( Neutral::isDescendant( newParent, orig ) ) {
		cout << "Error: Shell::doMove: Cannot move object to descendant in tree\n";
		return;
		
	}
	const string& name = orig.element()->getName();
	if ( Neutral::child( newParent.eref(), name ) != Id() ) {
			stringstream ss;
			ss << "Shell::doMove: Object with same name already present: '"
			   	<< newParent.path() << "/" << name << "'. Move failed.";
			warning( ss.str() );
			return;
	}

	SetGet2< Id, ObjId >::set( ObjId(), "move", orig, newParent );
	// innerMove( orig, newParent );
}
Esempio n. 6
0
void Shell::recvGet( const Eref& e, const Qinfo* q, PrepackedBuffer pb )
{
	if ( myNode_ == 0 ) {
		if ( gettingVector_ ) {
			ObjId tgt = q->src();
			// unsigned int linearIndex = q->src().eref().index().value();
			unsigned int linearIndex = 
				tgt.element()->dataHandler()->linearIndex( tgt.dataId );
			if ( linearIndex >= getBuf_.size() ) {
				if ( linearIndex >= getBuf_.capacity() )
					getBuf_.reserve( linearIndex * 2 );
				getBuf_.resize( linearIndex + 1 );
			}
			assert ( linearIndex < getBuf_.size() );
			double*& c = getBuf_[ linearIndex ];
			c = new double[ pb.dataSize() ];
			memcpy( c, pb.data(), pb.dataSize() * sizeof( double ) );
			// cout << myNode_ << ":" << q->threadNum() << ": Shell::recvGet[" << linearIndex << "]= (" << pb.dataSize() << ", " <<  *c << ")\n";
		} else  {
			assert ( getBuf_.size() == 1 );
			double*& c = getBuf_[ 0 ];
			c = new double[ pb.dataSize() ];
			memcpy( c, pb.data(), pb.dataSize() * sizeof( double ) );
			handleAck( 0, OkStatus );
		}
		++numGetVecReturns_;
	}
}
Esempio n. 7
0
// Utility function: return the compartment in which the specified
// object is located.
// Simply traverses the tree toward the root till it finds a
// compartment. Pools use a special msg, but this works for reacs too.
ObjId getCompt( Id id )
{
	ObjId pa = Neutral::parent( id.eref() ).id;
	if ( pa == ObjId() )
		return pa;
	else if ( pa.element()->cinfo()->isA( "ChemCompt" ) )
		return pa;
	return getCompt( pa );
}
Esempio n. 8
0
/// non-static func. Returns the Id found by traversing the specified path.
ObjId Shell::doFind( const string& path ) const
{
	if ( path == "/" || path == "/root" )
		return ObjId();

	ObjId curr;
	vector< string > names;
	vector< unsigned int > indices;
	bool isAbsolute = chopPath( path, names, indices );
	assert( names.size() == indices.size() );

	if ( !isAbsolute )
		curr = cwe_;

	for ( unsigned int i = 0; i < names.size(); ++i ) {
		if ( names[i] == "." ) {
		} else if ( names[i] == ".." ) {
			curr = Neutral::parent( curr.eref() );
		} else {
			ObjId pa = curr;
			curr = Neutral::child( curr.eref(), names[i] );
			if ( curr == ObjId() ) // Neutral::child returned Id(), ie, bad.
				return ObjId( 0, BADINDEX );
			if ( curr.element()->hasFields() ) {
				curr.dataIndex = pa.dataIndex;
				curr.fieldIndex = indices[i];
			} else {
				curr.dataIndex = indices[i];
				if ( curr.element()->numData() <= curr.dataIndex  )
					return ObjId( 0, BADINDEX );
			}
		}
	}
	
	assert( curr.element() );
	if ( curr.element()->numData() <= curr.dataIndex )
		return ObjId( 0, BADINDEX );
	if ( curr.fieldIndex > 0 && !curr.element()->hasFields() )
		return ObjId( 0, BADINDEX );

	return curr;
}
Esempio n. 9
0
ObjId SparseMsg::findOtherEnd( ObjId f ) const
{
	if ( f.element() == e1() ) {
		const unsigned int* entry;
		const unsigned int* colIndex;
		unsigned int num = matrix_.getRow( f.dataIndex, &entry, &colIndex );
		if ( num > 0 ) { // Return the first matching entry.
			return ObjId( e2()->id(), colIndex[0] );
		}
		return ObjId( 0, BADINDEX );
	} else if ( f.element() == e2() ) { // Bad! Slow! Avoid!
		vector< unsigned int > entry;
		vector< unsigned int > rowIndex;
		unsigned int num = matrix_.getColumn( f.dataIndex, entry, rowIndex );
		if ( num > 0 ) { // Return the first matching entry.
				return ObjId( e1()->id(), DataId( rowIndex[0] ) );
		}
	}
	return ObjId( 0, BADINDEX );
}
Esempio n. 10
0
bool Shell::innerMove( Id orig, ObjId newParent )
{
	static const Finfo* pf = Neutral::initCinfo()->findFinfo( "parentMsg" );
	static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf );
	static const FuncId pafid = pf2->getFid();
	static const Finfo* f1 = Neutral::initCinfo()->findFinfo( "childOut" );

	assert( !( orig == Id() ) );
	assert( !( newParent.element() == 0 ) );

	ObjId mid = orig.element()->findCaller( pafid );
	Msg::deleteMsg( mid );

	Msg* m = new OneToAllMsg( newParent.eref(), orig.element(), 0 );
	assert( m );
	if ( !f1->addMsg( pf, m->mid(), newParent.element() ) ) {
		cout << "move: Error: unable to add parent->child msg from " <<
			newParent.element()->getName() << " to " << 
			orig.element()->getName() << "\n";
		return 0;
	}
	return 1;
}
Esempio n. 11
0
/**
 * Static utility function. Attaches child element to parent element.
 * Must only be called from functions executing in parallel on all nodes,
 * as it does a local message addition
 * MsgIndex is needed to be sure that the same msg identifies parent-child
 * connection on all nodes.
 */
bool Shell::adopt( ObjId parent, Id child, unsigned int msgIndex ) {
	static const Finfo* pf = Neutral::initCinfo()->findFinfo( "parentMsg" );
	// static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf );
	// static const FuncId pafid = pf2->getFid();
	static const Finfo* f1 = Neutral::initCinfo()->findFinfo( "childOut" );

	assert( !( child.element() == 0 ) );
	assert( !( child == Id() ) );
	assert( !( parent.element() == 0 ) );

	Msg* m = new OneToAllMsg( parent.eref(), child.element(), msgIndex );
	assert( m );

	// cout << myNode_ << ", Shell::adopt: mid = " << m->mid() << ", pa =" << parent << "." << parent()->getName() << ", kid=" << child << "." << child()->getName() << "\n";

	if ( !f1->addMsg( pf, m->mid(), parent.element() ) ) {
		cout << "move: Error: unable to add parent->child msg from " <<
			parent.element()->getName() << " to " << 
			child.element()->getName() << "\n";
		return 0;
	}
	return 1;
}
Esempio n. 12
0
ObjId Neutral::parent( ObjId oid )
{
	static const Finfo* pf = neutralCinfo->findFinfo( "parentMsg" );
	static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf );
	static const FuncId pafid = pf2->getFid();

	if ( oid.id == Id() ) {
		cout << "Warning: Neutral::parent: tried to take parent of root\n";
		return Id();
	}

	ObjId mid = oid.element()->findCaller( pafid );
	assert( mid != ObjId() );

	ObjId pa = Msg::getMsg( mid )->findOtherEnd( oid );
	return pa;
}
Esempio n. 13
0
/**
 * This is the version used by the parser. Acts as a blocking,
 * serial-like interface to a potentially multithread, multinode call.
 * Returns the new Id index upon success, otherwise returns Id().
 * The data of the new Element is not necessarily allocated at this point,
 * that can be deferred till the global Instantiate or Reset calls.
 * Idea is that the model should be fully defined before load balancing.
 *
 */
Id Shell::doCreate( string type, ObjId parent, string name, 
				unsigned int numData, 
				NodePolicy nodePolicy,
				unsigned int preferredNode )
{
#ifdef ENABLE_LOGGER
    clock_t t = clock();
#endif
	const Cinfo* c = Cinfo::find( type );
	if ( !isNameValid( name ) ) {
		stringstream ss;
		ss << "Shell::doCreate: bad character in name'" << name << 
				"'. No Element created";
		warning( ss.str() );
		return Id();
	}

	if ( c ) {
		if ( c->banCreation() ) {
			stringstream ss;
			ss << "Shell::doCreate: Cannot create an object of class '" <<
				type << "' because it is an abstract base class or a FieldElement.\n";
			warning( ss.str() );
			return Id();
		}
		Element* pa = parent.element();
		if ( !pa ) {
			stringstream ss;
			ss << "Shell::doCreate: Parent Element'" << parent << "' not found. No Element created";
			warning( ss.str() );
			return Id();
		}
		if ( Neutral::child( parent.eref(), name ) != Id() ) {
			stringstream ss;
			ss << "Shell::doCreate: Object with same name already present: '"
				   	<< parent.path() << "/" << name << "'. No Element created";
			warning( ss.str() );
			return Id();
		}
		// Get the new Id ahead of time and pass to all nodes.
		Id ret = Id::nextId();
		NodeBalance nb( numData, nodePolicy, preferredNode );
		// Get the parent MsgIndex ahead of time and pass to all nodes.
		unsigned int parentMsgIndex = OneToAllMsg::numMsg();

		SetGet6< string, ObjId, Id, string, NodeBalance, unsigned int >::set(
			ObjId(), // Apply command to Shell
			"create",	// Function to call.
			type, 		// class of new object
			parent,		// Parent
			ret,		// id of new object
			name,		// name of new object
			nb,			// Node balance configuration
			parentMsgIndex	// Message index of child-parent msg.
		);
		// innerCreate( type, parent, ret, name, numData, isGlobal );

#ifdef ENABLE_LOGGER 
        logger.creationTime.push_back((float(clock() - t)/CLOCKS_PER_SEC));
#endif

		return ret;
	} else {
		stringstream ss;
		ss << "Shell::doCreate: Class '" << type << "' not known. No Element created";
		warning( ss.str() );
	}

#ifdef ENABLE_LOGGER 
        logger.creationTime.push_back((float(clock() - t)/CLOCKS_PER_SEC));
#endif
	return Id();
}