package cnslab.cnsnetwork;
import java.io.*;
import java.util.concurrent.*;
import jpvm.*;
import cnslab.cnsmath.Seed;
import edu.jhu.mb.ernst.engine.DiscreteEvent;
import edu.jhu.mb.ernst.engine.DiscreteEventQueue;
import edu.jhu.mb.ernst.engine.queue.DiscreteEventQueueLib;
/***********************************************************************
* The thread used by NetHost to do the real work, i.e. process the queue
* events. It also checks whether process proceeding is allowed or not.
*
* @version
* $Date: 2012-08-04 20:43:22 +0200 (Sat, 04 Aug 2012) $
* $Rev: 104 $
* $Author: croft $
* @author
* Yi Dong
* @author
* David Wallace Croft
***********************************************************************/
public final class PRun
implements Runnable
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
{
/** Fire event id */
public static final int FIRE_EVENT = 0;
/** internal Input event id */
public static final int INPUT_EVENT = 1;
/** Poisson Input event id */
public static final int POI_EVENT = 2;
/** Reset id */
@Deprecated
public static final int RESET = 3;
public static final int DISCRETE_EVENT = 4;
//
/** Minimum of synaptic delay */
public double minTime;
//
private final Network network;
private final Object lock;
private final CyclicBarrier barrier;
private final DiscreteEventQueue
discreteEventQueue;
//
private FireEvent firstFireEvent;
private InputEvent firstInputEvent;
private PInputEvent pInputEvent;
private int type;
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
public PRun (
final DiscreteEventQueue discreteEventQueue,
final Network network,
final Object lock,
final CyclicBarrier barrier )
////////////////////////////////////////////////////////////////////////
{
this.discreteEventQueue = discreteEventQueue;
this.network = network;
this.lock = lock;
this.barrier = barrier;
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/***********************************************************************
* @return
* true if the communication thread is allowed to proceed
***********************************************************************/
public boolean runAllowed ( )
////////////////////////////////////////////////////////////////////////
{
// if(network.stop) return true;
// take out the first fire element
firstFireEvent = network.getFirstFireEvent ( );
// take out the first input element
firstInputEvent = network.getFirstInputEvent ( );
// take out the first poisson input element
pInputEvent = network.getFirstPInputEvent ( );
final DiscreteEvent discreteEvent = discreteEventQueue.peek ( );
double
fireTime,
inputTime,
pInputTime,
discreteEventTime;
// System.out.println("running...");
if ( firstFireEvent != null )
{
fireTime = firstFireEvent.time;
}
else
{
fireTime = Double.MAX_VALUE;
}
if ( firstInputEvent != null )
{
inputTime = firstInputEvent.time;
}
else
{
inputTime = Double.MAX_VALUE;
}
if ( pInputEvent != null )
{
pInputTime = pInputEvent.time;
}
else
{
pInputTime = Double.MAX_VALUE;
}
if ( discreteEvent != null )
{
discreteEventTime = discreteEvent.getTime ( );
}
else
{
discreteEventTime = Double.MAX_VALUE;
}
if ( fireTime < inputTime )
{
type = PRun.FIRE_EVENT;
minTime = fireTime;
}
else
{
type = PRun.INPUT_EVENT;
minTime = inputTime;
}
if ( minTime > pInputTime )
{
type = PRun.POI_EVENT;
minTime = pInputTime;
}
if ( minTime > discreteEventTime )
{
type = PRun.DISCRETE_EVENT;
minTime = discreteEventTime;
return true;
}
/*
if(poiInput==null && firstInput==null && firstFire==null)
{
type=PRun.RESET;
network.p.println("network reset");
return true;
}
*/
// if(network.rootTime+network.minDelay>network.endOfTrial)
// {
// return true;
// }
if ( network.info.numTasks == 1
&& network.experiment.recorder.intraEle.size ( ) == 0 )
{
network.spikeState = true;
return true;
}
/* test it
if(network.rootTime+network.minDelay<minTime)
{
// network.p.println(
// "root time"+network.rootTime+" systime:"+minTime);
return false;
}
*/
/*
if ( type == PRun.FIRE_EVENT
&& firstFire.index == network.neurons.length + network.base - 1
&& minTime > network.endOfTrial
&& network.rootTime + network.minDelay/2.0 < network.endOfTrial)
{
return false;
}
*/
if ( type == PRun.FIRE_EVENT
&& firstFireEvent.index
== network.neurons.length + network.base - 1 )
{
// tick neuron
network.spikeState = true;
for ( int iter = 0; iter < network.info.numTasks; iter++ )
{
if ( iter != network.info.idIndex
&& network.received [ iter ] == 0 )
{
network.spikeState = false;
}
}
// network.p.println("state "+ network.spikeState);
//
// for(int it=0;it<network.info.numTasks;it++)
// {
// if(it!=network.info.idIndex && !network.received[it].empty())
// {
// network.p.println(
// "host:"+it+" value"+(Double)(network.received[it].peek()));
// }
// }
if ( !network.spikeState )
{
// if(network.rootTime>network.endOfTrial)return true;
// network.p.println(
// "tick neuron stuck at "
// + minTime + "root Time"+network.rootTime);
// network.p.println( "type "+type+" spkikeState"
// +network.spikeState + " neuron id: "+ firstFire.index);
// for(int iter=0;iter<network.info.numTasks;iter++)
// {
// if(iter!=network.info.idIndex)
// {
// network.p.print(
// "host"+iter+" "+network.received[iter].empty());
// }
// }
return false;
}
// network.p.println("tick neuron run through "+minTime);
for ( int iter = 0; iter < network.info.numTasks; iter++ )
{
if ( iter != network.info.idIndex && !network.trialDone )
{
// network.p.println("pop"+iter);
( network.received [ iter ] )--;
}
}
network.spikeState = false;
if ( network.info.numTasks == 1 )
{
network.spikeState = true;
}
return true;
}
return true;
}
@Override
public void run ( )
////////////////////////////////////////////////////////////////////////
{
try
{
// Thread.sleep(100);
// double tmp_firetime;
// boolean isFire;
final Seed seed = network.seed;
network.p.println ( "seed " + seed.seed );
// network.saveSeed = network.idum.seed;
// synchronized (synLock)
// {
while ( !network.stop )
{
// network.info.jpvm.pvm_barrier(
// network.info.parent.getHost(),
// network.subExpId*network.exp.subExp.length+network.trialId,
// network.info.numTasks);
// synchronized (synLock)
// {
// network.p.println("trial wait");
//
// synLock.wait(); //synchronizing lock
//
// network.p.println("begin");
// }
//
// lock.wait();
//
// synchronized(synLock)
// {
// network.p.println(" wait begin");
// network.p.flush();
// network.idum.seed = network.saveSeed;
// network.p.println("Run over seed "+network.idum.seed);
//
// while(!network.startSig)
// {
// jpvmBuffer buff = new jpvmBuffer();
//
// network.info.jpvm.pvm_send(
// buff,
// network.info.parent,
// NetMessageTag.syncTrialHost); //send to trialHost
barrier.await ( );
// }
//
// network.startSig=false;
//
// network.p.println("Run start seed "+network.idum.seed);
//
// network.p.println(" wait end");
//
// network.p.flush();
// }
synchronized (lock)
{
// network.p.print("trial startting");
// network.p.flush();
// jpvmBuffer buf = new jpvmBuffer();
// buf.pack(network.recordBuff);
// network.info.jpvm.pvm_send(
// buf,
// network.info.parent,
// NetMessageTag.trialDone);
// network.p.print(
// "after wait "+"E"+network.subExpId+" T"+network.trialId);
// network.p.flush();
// System.out.println("out");
// network.p.println("before init");
network.init ( );
// Thread.sleep(100);
// network.p.println("after init");
// network.p.flush();
network.rootTime = 0.0;
network.recordBuff.buff.clear ( );
network.intraRecBuffers.init ( );
// network.p.println("after init seed "+network.idum.seed);
// network.p.println("all initialized");
// network.p.println(
// "ini done and trialDone is "+ network.trialDone);
// network.p.flush();
/*
network.rootTime=0.0;
network.fireQueue.clear();
network.inputQueue.clear();
network.poissonQueue.clear();
network.init();
*/
//
// lock.notify();
// network.p.println("Communication is running");
while ( !network.trialDone )
{
// network.p.println("Communication inside");
// while ( !communicationAllowed(
// firstFire=( ((tmpFire=network.fireQueue.firstItem())
// !=null) ?
// new FireEvent(tmpFire.index, tmpFire.time) : null )))
while ( !runAllowed ( ) && !network.trialDone )
{
// network.p.println("lock at"+minTime );
// network.p.flush();
// System.out.println("lock at"+minTime);
lock.wait ( 1000 );
if ( network.trialDone )
{
break;
}
}
if ( !network.trialDone )
{
// network.p.println("process "+type );
// network.p.flush();
switch ( type )
{
case PRun.DISCRETE_EVENT:
DiscreteEventQueueLib.process ( discreteEventQueue );
break;
case PRun.FIRE_EVENT:
// network.p.println("fire event process "+minTime );
network.pFireProcess ( firstFireEvent );
break;
case PRun.INPUT_EVENT:
// network.p.println("input event process "+minTime );
network.pInputProcess ( firstInputEvent );
break;
case PRun.POI_EVENT:
//network.p.println("Poisson event process "+minTime );
network.pPoissonProcess ( pInputEvent );
break;
default:
break;
}
}
} // END: while
}
} // END: while
}
catch ( jpvmException exx )
{
try
{
final FileOutputStream out = new FileOutputStream (
"log/"+network.info.jpvm.pvm_mytid().getHost()
+ "error"+network.info.idIndex+".txt" );
final PrintStream p = new PrintStream ( out );
exx.printStackTrace ( p );
p.close ( );
// System.exit(0);
}
catch ( Exception ex )
{
//
}
}
catch(InterruptedException ex)
{
//TODO: Add Exception handler here
ex.printStackTrace();
}
catch(Exception a)
{
a.printStackTrace ( );
try
{
FileOutputStream out = new FileOutputStream (
"log/"+network.info.jpvm.pvm_mytid().getHost()
+"error"+network.info.idIndex+".txt");
final PrintStream printStream = new PrintStream ( out );
a.printStackTrace(printStream);
printStream.println("input from neuron");
printStream.println(firstInputEvent);
printStream.println("input from external source");
printStream.println(pInputEvent);
printStream.close();
System.exit(0);
}
catch(Exception ex)
{
ex.printStackTrace ( );
}
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
}