Example #1
0
void Element::setTick( int t )
{
	Id clockId( 1 );
	if ( t == tick_ )
		return;
	if ( tick_ >= 0 ) { // Drop all messages coming here from clock.
		dropAllMsgsFromSrc( clockId );
	}
	tick_ = t;
	if ( t < 0 || t > 31 ) {  // Only 32 ticks available.
		// Don't need to add new ticks.
		return;
	}
	const Finfo* f2 = cinfo()->findFinfo( "init" );
	if ( f2 && dynamic_cast< const SharedFinfo* >( f2 ) ) { 
		// Must build init msg too. This comes on the previous tick.
		assert( t > 0 );
		addClockMsg( t-1, id(), f2 );
	}
	f2 = cinfo()->findFinfo( "proc" );
	if ( f2 ) { 
		addClockMsg( t, id(), f2 );
	} else {
		cout << "Element::setTick:Warning: Attempt to assign a tick to a '"
		<< cinfo_->name() << "'.\nThis does not support process actions.\n";
		tick_ = -1;
	}
}
Example #2
0
/**
 * Static function, used to flip flags to start or end a simulation. 
 * It is used as the within-barrier function of barrier 3.
 * This has to be in the barrier as we are altering a Clock field which
 * the 'process' flag depends on.
 * Six cases:
 * 	- Do nothing
 * 	- Reinit only
 *	- Reinit followed by start
 *	- Start only
 *	- Stop only
 *	- Stop followed by Reinit.
 * Some of these cases need additional intermediate steps, since the reinit
 * flag has to turn itself off after one cycle.
 */
void Clock::checkProcState()
{
	/// Handle pending Reduce operations.
	Qinfo::clearReduceQ( Shell::numProcessThreads() );

	if ( procState_ == NoChange ) { // Most common 
		return;
	}

	Id clockId( 1 );
	assert( clockId() );
	Clock* clock = reinterpret_cast< Clock* >( clockId.eref().data() );

	switch ( procState_ ) {
		case TurnOnReinit:
			clock->doingReinit_ = 1;
		//	procState_ = TurnOffReinit;
		break;
		case TurnOffReinit:
			clock->doingReinit_ = 0;
			procState_ = NoChange;
		break;
		case ReinitThenStart:
			clock->doingReinit_ = 1;
			procState_ = StartOnly;
		break;
		case StartOnly:
			clock->doingReinit_ = 0;
			clock->isRunning_ = 1;
			procState_ = NoChange;
		break;
		case StopOnly:
			clock->isRunning_ = 0;
			procState_ = NoChange;
		break;
		case StopThenReinit:
			clock->isRunning_ = 0;
			clock->doingReinit_ = 1;
		//	procState_ = TurnOffReinit;
		break;
		case NoChange:
		default:
		break;
	}
}
Example #3
0
double Neutral::getDt( const Eref& e ) const
{
	int tick = e.element()->getTick();
	if ( tick < 0 ) 
		return 0.0;
	Id clockId( 1 );
	return LookupField< unsigned int, double >::get(
		clockId, "tickDt", tick );
}
Example #4
0
void Shell::doReinit( )
{

#ifdef ENABLE_LOGGER
        clock_t t = clock();
        cout << logger.dumpStats(0);
#endif
	Id clockId( 1 );
	SetGet0::set( clockId, "reinit" );

#ifdef ENABLE_LOGGER
       float time = (float(clock() - t)/CLOCKS_PER_SEC);
       logger.initializationTime.push_back(time);
#endif
}
Example #5
0
void Shell::doStart( double runtime )
{
#ifdef ENABLE_LOGGER
        clock_t t = clock();
        stringstream ss;
        ss << "Running moose for " << runtime << " seconds";
        logger.log("INFO", ss.str());
#endif
	Id clockId( 1 );
	SetGet1< double >::set( clockId, "start", runtime );

#ifdef ENABLE_LOGGER
        float time = (float(clock() - t) / CLOCKS_PER_SEC);
        logger.simulationTime.push_back(time);
#endif
}
Example #6
0
/**
 * In phase2 it advances the internal counter to move to the next tick,
 * and when all ticks for this TickManager are done, to move to the next
 * TickManager.
 */
void Clock::reinitPhase2( ProcInfo* info )
{
	info->currTime = 0.0;

	if ( Shell::isSingleThreaded() || info->threadIndexInGroup == 1 ) {
		if ( tickPtr_.size() == 0 || 
					tickPtr_[ currTickPtr_ ].mgr()->reinitPhase2( info ) ) {
			++currTickPtr_;
			if ( currTickPtr_ >= tickPtr_.size() ) {
				Id clockId( 1 );
				ack()->send( clockId.eref(), info->threadIndexInGroup,
					info->nodeIndexInGroup, OkStatus );
				procState_ = TurnOffReinit;
				++countReinit2_;
			}
		}
	}
}
Example #7
0
// In phase 2 we need to do the updates to the Clock object, especially
// sorting the TickPtrs. This also is when we find out if the simulation
// is finished.
// Note that this function happens when lots of other threads are doing
// things. So it cannot touch any fields which might affect other threads.
void Clock::advancePhase2(  ProcInfo *p )
{
	if ( Shell::isSingleThreaded() || p->threadIndexInGroup == 1 ) {
		tickPtr_[0].mgr()->advancePhase2( p );
		if ( tickPtr_.size() > 1 )
			sort( tickPtr_.begin(), tickPtr_.end() );
		currentTime_ = tickPtr_[0].mgr()->getNextTime() - 
			tickPtr_[0].mgr()->getDt();
		if ( currentTime_ > endTime_ ) {
			Id clockId( 1 );
			procState_ = StopOnly;
			finished()->send( clockId.eref(), p->threadIndexInGroup );
			ack()->send( clockId.eref(), p->threadIndexInGroup, 
				p->nodeIndexInGroup, OkStatus );
		}
		++countAdvance2_;
	}
}
Example #8
0
static bool addClockMsg( unsigned int tick, Id tgt, const Finfo* f2 )
{
	Id clockId( 1 );
	stringstream ss;
	ss << "proc" << tick;
	
	const Finfo* f1 = clockId.element()->cinfo()->findFinfo( ss.str() );
	assert( f1 );
	assert( f2 );
	Msg* m = new OneToAllMsg( clockId.eref(), tgt.element(), 0 );
	if ( m ) {
		if ( f1->addMsg( f2, m->mid(), clockId.element() ) ) {
			return true;
		}
		delete m;
	}
	cout << "Error: Element::setTick: failed to connect " << tgt << 
			" to clock\n";
	return false;
}
Example #9
0
// Non-static function. The innerAddMsg needs the shell.
void Shell::addClockMsgs( 
	const vector< ObjId >& list, const string& field, unsigned int tick,
   	unsigned int msgIndex	)
{
	if ( !Id( 1 ).element() )
		return;
	ObjId clockId( 1 );
	dropClockMsgs( list, field ); // Forbid duplicate PROCESS actions.
	for ( vector< ObjId >::const_iterator i = list.begin(); 
		i != list.end(); ++i ) {
		if ( i->element() ) {
			stringstream ss;
			ss << "proc" << tick;
			const Msg* m = innerAddMsg( "OneToAll",
				clockId, ss.str(), 
				*i, field, msgIndex++ );
			if ( m )
				i->element()->innerSetTick( tick );
		}
	}
}
Example #10
0
void Shell::doStop( )
{
	Id clockId( 1 );
	SetGet0::set( clockId, "stop" );
}