00001 #include "DistributedSimEngine.h"
00002 #include "SimNetwork.h"
00003 #include <iostream>
00004
00005 using std::cerr;
00006 using std::cout;
00007 using std::endl;
00008
00009
00010 DistributedSimEngine::DistributedSimEngine(SimEngine &localEngine,
00011 DistributedIncomingSpikeScheduler &incomingScheduler,
00012 SpikeScheduler &spikeScheduler,
00013 DistributedCycledAnalogMsgDispatcher &distCycledAnalogMsgDispatcher,
00014 MPIAllToAllCommunicator &mpiCommunicator,
00015 SimNetwork &net) :
00016 SimEngine((int)0,spikeScheduler,net), localEng(localEngine), inScheduler(incomingScheduler),
00017 _mpiCommunicator(mpiCommunicator), distCycledAnalogMsgDispatcher(distCycledAnalogMsgDispatcher)
00018 {
00019 currentStepWithinCycle = 0;
00020 }
00021
00022 DistributedSimEngine::~DistributedSimEngine()
00023 {}
00024
00025 void DistributedSimEngine::advance(int numSteps)
00026 {
00027 int nCycles;
00028 int reminderSteps;
00029 int interval = default_steps_per_cycle ;
00030 int leftStepsToFinishPreviousCycle;
00031
00032
00033 if (currentStepWithinCycle) {
00034 if (numSteps + currentStepWithinCycle >= interval) {
00035 leftStepsToFinishPreviousCycle = default_steps_per_cycle - currentStepWithinCycle;
00036 localEng.advanceSeveralStepsWithinACycle(leftStepsToFinishPreviousCycle);
00037 localEng.finalizeCycle();
00038 bool finished = false;
00039
00040 while (!finished) {
00041 finished = _mpiCommunicator.doAllToAllExchange();
00042 inScheduler.processMPIInputSpikeBuffers();
00043 }
00044 distCycledAnalogMsgDispatcher.dispatchDelayerCycledIncomingAnalogMsgs();
00045 } else {
00046 leftStepsToFinishPreviousCycle = numSteps;
00047 localEng.advanceSeveralStepsWithinACycle(leftStepsToFinishPreviousCycle);
00048 }
00049 numSteps -= leftStepsToFinishPreviousCycle;
00050 }
00051
00052 reminderSteps = numSteps % interval;
00053 nCycles = (numSteps - reminderSteps) / interval;
00054
00055
00056 for (int c = 0 ; c < nCycles ; ++c ) {
00057 localEng.advanceOneFullCycle();
00058 bool finished = false;
00059
00060 while (!finished) {
00061 finished = _mpiCommunicator.doAllToAllExchange();
00062 inScheduler.processMPIInputSpikeBuffers();
00063 }
00064
00065 distCycledAnalogMsgDispatcher.dispatchDelayerCycledIncomingAnalogMsgs();
00066 }
00067
00068 if (reminderSteps > 0 ) {
00069 localEng.advanceSeveralStepsWithinACycle(reminderSteps);
00070
00071 bool finished = false;
00072 while (!finished) {
00073 finished = _mpiCommunicator.doAllToAllExchange();
00074 inScheduler.processMPIInputSpikeBuffers();
00075 }
00076 distCycledAnalogMsgDispatcher.dispatchDelayerCycledIncomingAnalogMsgs();
00077 }
00078 currentStepWithinCycle = reminderSteps;
00079
00080 }
00081
00082
00083 void DistributedSimEngine::advanceSeveralStepsWithinACycle(int nsteps)
00084 {
00085 localEng.advanceSeveralStepsWithinACycle(nsteps);
00086 }
00087
00088 void DistributedSimEngine::advanceOneFullCycle()
00089 {
00090 localEng.advanceOneFullCycle();
00091 bool finished = false;
00092
00093 while (!finished) {
00094 finished = _mpiCommunicator.doAllToAllExchange();
00095 inScheduler.processMPIInputSpikeBuffers();
00096 }
00097 distCycledAnalogMsgDispatcher.dispatchDelayerCycledIncomingAnalogMsgs();
00098 }
00099
00100 void DistributedSimEngine::finalizeCycle()
00101 {
00102 localEng.finalizeCycle();
00103 bool finished = false;
00104
00105 while (!finished) {
00106 finished = _mpiCommunicator.doAllToAllExchange();
00107 inScheduler.processMPIInputSpikeBuffers();
00108 }
00109 distCycledAnalogMsgDispatcher.dispatchDelayerCycledIncomingAnalogMsgs();
00110 }
00111
00112 void DistributedSimEngine::reset()
00113 {
00114 localEng.reset();
00115 currentStepWithinCycle = 0;
00116 }
00117
00118 void DistributedSimEngine::initialize()
00119 {
00120 localEng.initialize();
00121 }
00122
00123 void DistributedSimEngine::addObject( SimObjectFactory const& objFactory, SimObject::ID &id )
00124 {
00125 localEng.addObject(objFactory, id);
00126 }
00127
00128 void DistributedSimEngine::mount( const SimObjectFactory &objFactory, const SimObject::ID &mountpoint, SimObject::ID &gid )
00129 {
00130 localEng.mount( objFactory, mountpoint, gid );
00131 }
00132
00133 void DistributedSimEngine::insert( const SimObjectFactory &objFactory, const SimObject::ID &mountpoint, SimObject::ID &gid )
00134 {
00135 localEng.insert( objFactory, mountpoint, gid );
00136 }
00137
00138 SimObject *DistributedSimEngine::getObject(const SimObject::ID &id)
00139 {
00140 return localEng.getObject(id);
00141 }