16 int papiEventSet = PAPI_NULL;
20 inline void AccumulateCounters(
long long *tick,
long long *tock,
long long *clock)
22 for(
int iCounter = 0;iCounter < numCounters;iCounter++)
23 clock[iCounter] += (tock[iCounter] - tick[iCounter]);
28 #ifndef _ADVANCER_TIMERS_ 29 #define _ADVANCER_TIMERS_ 35 static const int RHS = 2;
36 static const int IGX = 4;
42 template<
typename DomainType>
47 enum {ZAXPYKERNEL=0,RKSUMKERNEL,NUMTIMERS};
52 using DomainAdvancerType::messageStreamPtr;
53 using DomainAdvancerType::domainPtr;
54 using DomainAdvancerType::advancerConfig;
58 typedef typename DomainType::GridType
GridType;
60 typedef typename DomainType::HaloType
HaloType;
62 typedef typename DomainType::RHSType
RHSType;
67 numStages(4), rkH(0.0)
69 stageWeights.resize(4,0.5);
70 stageWeights[2] = 1.0;
71 stageWeights[3] = 1.0/6.0;
72 updateWeights.resize(4,1.0/3.0);
73 updateWeights[0] = 1.0/6.0;
74 updateWeights[3] = 1.0/6.0;
76 communicateState =
false;
79 rk4advancer(DomainType &inDomain) : DomainAdvancerType(inDomain),
80 numStages(4), rkH(0.0)
82 stageWeights.resize(4,0.5);
83 stageWeights[2] = 1.0;
84 stageWeights[3] = 1.0/6.0;
85 updateWeights.resize(4,1.0/3.0);
86 updateWeights[0] = 1.0/6.0;
87 updateWeights[3] = 1.0/6.0;
88 InitilializeAdvancer(inDomain,std::cout);
90 communicateState =
false;
94 DomainType &inDomain) : DomainAdvancerType(inDomain),
95 numStages(4), rkH(0.0)
97 stageWeights.resize(4,0.5);
98 stageWeights[2] = 1.0;
99 stageWeights[3] = 1.0/6.0;
100 updateWeights.resize(4,1.0/3.0);
101 updateWeights[0] = 1.0/6.0;
102 updateWeights[3] = 1.0/6.0;
104 communicateState =
false;
106 InitilializeAdvancer(inDomain,std::cout);
110 { communicateState = onoff; };
112 { timersOn = onoff; };
115 advancerFields = inConfig.
GetValueVector<std::string>(
"AdvancerFields");
134 rkH = domainPtr->TimeStep();
139 { rhsHandlerPtr = &inRHS; };
150 messageStreamPtr = &inStream;
172 SetRHS(inDomain.RHS());
174 SetMessageStream(inStream);
176 domainPtr = &inDomain;
177 numGrids = inDomain.NumberOfLocalGrids();
180 inStream <<
"rk4advancer:Error: No grids found for domain." << std::endl;
185 rhsHandlers.resize(numGrids,NULL);
187 numPointsGrids.resize(numGrids);
188 stateMessageIds.resize(numGrids);
189 gridFortranIntervals.resize(numGrids);
190 gridTimes.resize(numGrids,NULL);
192 inStream <<
"rk4advancer:Status: Found " << numGrids <<
" grids in domain." << std::endl;
194 for(
int i = 0;i < NUMTIMERS;i++){
195 advancerTimers[i] = 0.0;
197 advancerCounters[i] =
new long long [numCounters];
198 for(
int iCount = 0;iCount < numCounters;iCount++){
199 advancerCounters[i][iCount] = 0;
208 numThreads = omp_get_max_threads();
211 inStream <<
"rk4advancer:Status: Setting up for " << numThreads <<
" threads." << std::endl;
213 threadStage.resize(numThreads);
214 threadGrid.resize(numThreads);
216 stageStates.resize(numGrids);
217 stageKs.resize(numGrids);
218 gridNeighbors.resize(numGrids);
220 for(
int iLocalGrid = 0;iLocalGrid < numGrids;iLocalGrid++){
222 int iGrid = inDomain.LocalGridIndex(iLocalGrid);
224 rhsHandlers[iLocalGrid] = &inDomain.RHS(iGrid);
226 GridType &domainGrid(inDomain.Grid(iGrid));
227 HaloType &gridHalo(inDomain.Grid(iGrid).Halo());
228 StateType &gridState(inDomain.State(iGrid));
229 StateType dummyParams;
230 StateType *paramPtr = &dummyParams;
232 std::vector<StateType *> &gridParamVec(inDomain.Params());
233 if(gridParamVec.size() == numGrids){
234 if(gridParamVec[iGrid] != NULL)
235 paramPtr = gridParamVec[iGrid];
237 StateType &gridParams(*paramPtr);
240 gridFortranIntervals[iLocalGrid].resize(numThreads);
244 int numDim = domainGrid.Dimension();
245 const std::vector<double> &dX(domainGrid.DX());
247 const std::vector<size_t> &
bufferSizes(domainGrid.BufferSizes());
248 size_t numPoints = domainGrid.BufferSize();
254 int timeHandle = gridState.GetDataIndex(
"simTime");
258 gridTimes[iLocalGrid] = timeData.
Data<
double>();
259 inStream <<
"rk4advancer:Status: Using state-supplied time (" 260 << gridTimes[iLocalGrid] <<
")" << std::endl;
262 inStream <<
"rk4advancer:Warning: Time data not supplied in state! Using dummy time." 264 gridTimes[iLocalGrid] = &myTime;
265 *gridTimes[iLocalGrid] = 0.0;
267 myTime = inDomain.Time();
268 *gridTimes[iLocalGrid] = myTime;
270 rkH = domainPtr->TimeStep();
272 inStream <<
"rk4advancer:Error: Received negative timestep (" << rkH <<
") from " 273 <<
"RHS object. Aborting initialization." << std::endl;
275 }
else if (rkH == 0.0){
276 inStream <<
"rk4advancer:Warning: Received ZERO timestep at setup. Advancer will not update time." 280 numStateFields = gridState.NumStateFields();
281 inStream <<
"rk4advancer:Status: Number of state fields = " 282 << numStateFields << std::endl;
284 stageStates[iLocalGrid].resize(1);
285 stageKs[iLocalGrid].resize(numStages);
286 stageStates[iLocalGrid][0].CopyStateData(gridState);
287 for(
int iStage = 0;iStage < numStages;iStage++){
290 stageKs[iLocalGrid][iStage].CopyStateData(gridState);
293 gridComm.CartNeighbors(gridNeighbors[iLocalGrid]);
296 if(communicateState){
297 inStream <<
"rk4advancer: Setting up message for state communication." 299 stateMessageIds[iLocalGrid] = SetupStateMessage(gridState,gridHalo);
300 if(stateMessageIds[iLocalGrid] < 0){
302 <<
"rk4advancer:Error: Could not set up state message for Grid(" 303 << iLocalGrid+1 <<
"," << iGrid+1 <<
")." 310 inStream <<
"rk4advancer:Status: Initialized advancer at time = " 311 << myTime << std::endl;
317 int numVar = inState.NumStateVar();
318 return(inHalo.CreateMessageBuffers(numVar));
322 int messageId,
int threadId)
326 for(
int iField = 0;iField < numStateFields;iField++){
328 double *fieldData = inState.GetStateFieldData(iField);
330 inHalo.PackMessageBuffers(messageId,iVar,numComponents,fieldData);
338 int messageId,
int threadId)
343 for(
int iField = 0;iField < numStateFields;iField++){
345 double *fieldData = inState.GetStateFieldData(iField);
347 inHalo.UnPackMessageBuffers(messageId,iVar,numComponents,fieldData);
360 myThreadId = omp_get_thread_num();
363 DomainType &inDomain(*domainPtr);
365 for(
int iLocalGrid = 0;iLocalGrid < numGrids;iLocalGrid++){
367 int iGrid = inDomain.LocalGridIndex(iLocalGrid);
369 GridType &domainGrid(inDomain.Grid(iGrid));
370 HaloType &gridHalo(domainGrid.Halo());
371 StateType &gridState(inDomain.State(iGrid));
373 std::vector<int> &cartNeighbors(gridNeighbors[iLocalGrid]);
374 int stateMessageId = stateMessageIds[iLocalGrid];
376 if(communicateState){
377 if(PackStateMessage(gridState,gridHalo,stateMessageId,myThreadId)){
378 SetError(
"PackStateMessage",gridComm);
387 gridHalo.SendMessage(stateMessageId,cartNeighbors,gridComm);
388 gridHalo.ReceiveMessage(stateMessageId,cartNeighbors,gridComm);
391 if(UnpackStateMessage(gridState,gridHalo,stateMessageId,myThreadId)){
392 SetError(
"UnpackStateMessage",gridComm);
411 myTime = myTime + rkH;
412 for(
int iGrid = 0;iGrid < numGrids;iGrid++)
413 *gridTimes[iGrid] = *gridTimes[iGrid] + rkH;
414 if(domainPtr->FinalizeAdvance(myTime))
422 StateType &stateUpdate)
427 virtual void SetError(
const std::string &errorMessage,
432 myThreadId = omp_get_thread_num();
434 int &rkStage(threadStage[myThreadId]);
436 std::ostringstream errOut;
438 errOut << errorMessage <<
" for RKstage = " << rkStage;
439 DomainAdvancerType::SetError(errOut.str(),inComm);
444 {
return(DomainAdvancerType::ErrorCheck(inComm)); };
463 myThreadId = omp_get_thread_num();
467 DomainType &simulationDomain(*domainPtr);
469 std::vector<GridType *> &domainGrids(simulationDomain.Grids());
470 std::vector<StateType *> &domainStates(simulationDomain.States());
471 std::vector<int> &globalGridIndices(simulationDomain.LocalGridIndices());
478 if(InitializeAdvance()){
488 int &rkStage(threadStage[myThreadId]);
489 int &rkGrid(threadGrid[myThreadId]);
491 for(rkStage = 0;rkStage < numStages;rkStage++){
493 for(rkGrid = 0;rkGrid < numGrids;rkGrid++){
497 int domainGridIndex = globalGridIndices[rkGrid];
500 long long counterTicks[MAXCOUNTERS];
501 long long counterTocks[MAXCOUNTERS];
504 StateType &baseState(*domainStates[domainGridIndex]);
505 GridType &domainGrid(*domainGrids[domainGridIndex]);
508 HaloType &gridHalo(domainGrid.Halo());
509 StateType &stageK(stageKs[rkGrid][rkStage]);
515 StateType *rkNextStatePtr = NULL;
516 StateType *rkInputStatePtr = NULL;
518 rkNextStatePtr = &stageStates[rkGrid][0];
520 rkInputStatePtr = domainStates[domainGridIndex];
522 rkInputStatePtr = &stageStates[rkGrid][0];
525 rkNextStatePtr = domainStates[domainGridIndex];
526 rkInputStatePtr = &stageStates[rkGrid][0];
528 StateType &rkNextState(*rkNextStatePtr);
529 StateType &rkInputState(*rkInputStatePtr);
531 std::vector<int> &cartNeighbors(gridNeighbors[rkGrid]);
532 int stateMessageId = stateMessageIds[rkGrid];
538 rhsHandlerPtr = rhsHandlers[rkGrid];
548 if(GetRHS(domainGrid,gridHalo,rkInputState,stageK,myThreadId)){
573 AXPY(stageWeights[rkStage]*rkH,stageK,baseState,rkNextState,rkGrid,myThreadId);
587 RKSum(rkGrid,myThreadId);
596 if(communicateState){
603 if(PackStateMessage(rkNextState,gridHalo,stateMessageId,myThreadId)){
604 SetError(
"PackStateMessage",gridComm);
617 gridHalo.SendMessage(stateMessageId,cartNeighbors,gridComm);
618 gridHalo.ReceiveMessage(stateMessageId,cartNeighbors,gridComm);
628 if(UnpackStateMessage(rkNextState,gridHalo,stateMessageId,myThreadId)){
629 SetError(
"UnpackStateMessage",gridComm);
642 if(InterGridExchange()){
652 if(FinalizeAdvance())
666 int GetRHS(GridType ¤tGrid,HaloType &gridHalo,StateType &inState,
667 StateType &stateRHS,
int myThreadId)
669 int &rkStage(threadStage[myThreadId]);
673 myGlobalPtr->FunctionEntry(
"SetupRHS");
676 if(rhsHandlerPtr->SetupRHS(currentGrid,inState,stateRHS,myThreadId)){
678 *messageStreamPtr <<
"rhsHandler::SetupRHS failed in rk stage " << rkStage
686 myGlobalPtr->FunctionExit(
"SetupRHS");
687 myGlobalPtr->FunctionEntry(
"RHS");
689 int rhsErrorCode = rhsHandlerPtr->RHS(myThreadId);
692 *messageStreamPtr <<
"rhsHandler::RHS failed in rk stage " << rkStage
693 <<
" with error code (" << rhsErrorCode <<
")" << std::endl;
700 myGlobalPtr->FunctionExit(
"RHS");
707 int AXPY(
double a,StateType &xState,StateType &yState,StateType &outState,
708 int localGridIndex,
int myThreadId)
712 long long counterTicks[MAXCOUNTERS];
713 long long counterTocks[MAXCOUNTERS];
716 DomainType &simulationDomain(*domainPtr);
717 std::vector<GridType *> &domainGrids(simulationDomain.Grids());
718 std::vector<int> &globalGridIndices(simulationDomain.LocalGridIndices());
719 int gridIndex = globalGridIndices[localGridIndex];
721 GridType &opGrid(*domainGrids[gridIndex]);
728 StateType tempState1(yState);
729 StateType tempState2(xState*a);
730 StateType tempState3(tempState1 + tempState2);
731 outState.Copy(tempState3);
735 double *nextTime = timeData.
Data<
double>();
737 *nextTime = *nextTime +
a;
743 std::vector<size_t> &myInterval(gridFortranIntervals[localGridIndex][myThreadId]);
744 int numDim = opGrid.Dimension();
745 std::vector<size_t> &numPointsX(opGrid.BufferSizes());
747 for(
int iField = 0;iField < numStateFields;iField++){
749 double *xData = xState.GetStateFieldData(iField);
750 double *yData = yState.GetStateFieldData(iField);
751 double *outData = outState.GetStateFieldData(iField);
755 for(
int iComponent = 0;iComponent <
numComponents;iComponent++){
759 double *xBuffer = &xData[compIndex];
760 double *yBuffer = &yData[compIndex];
761 double *zBuffer = &outData[compIndex];
769 PAPI_read(papiEventSet,counterTicks);
775 (&numDim,&
numPoints,&numPointsX[0],&myInterval[0],
776 &
a,xBuffer,yBuffer,zBuffer);
783 PAPI_read(papiEventSet,counterTocks);
784 AccumulateCounters(counterTicks,counterTocks,advancerCounters[ZAXPYKERNEL]);
795 int RKSum(
int localGridIndex,
int myThreadId)
799 long long counterTicks[MAXCOUNTERS];
800 long long counterTocks[MAXCOUNTERS];
803 DomainType &simulationDomain(*domainPtr);
804 std::vector<GridType *> &domainGrids(simulationDomain.Grids());
805 std::vector<int> &globalGridIndices(simulationDomain.LocalGridIndices());
807 int gridIndex = globalGridIndices[localGridIndex];
809 GridType &opGrid(*domainGrids[gridIndex]);
810 std::vector<StateType *> &domainStates(simulationDomain.States());
811 StateType &baseState(*domainStates[gridIndex]);
812 std::vector<StateType> &gridKs(stageKs[localGridIndex]);
819 baseState += (((gridKs[0] + gridKs[3])*(1.0/6.0) + (gridKs[1] + gridKs[2])*(1.0/3.0))*h);
825 std::vector<size_t> &myInterval(gridFortranIntervals[localGridIndex][myThreadId]);
826 std::vector<size_t> &numPointsX(opGrid.BufferSizes());
827 int numDim = opGrid.Dimension();
830 for(
int iField = 0;iField < numStateFields;iField++){
832 double *k1Data = gridKs[0].GetStateFieldData(iField);
833 double *k2Data = gridKs[1].GetStateFieldData(iField);
834 double *k3Data = gridKs[2].GetStateFieldData(iField);
835 double *k4Data = gridKs[3].GetStateFieldData(iField);
836 double *baseData = baseState.GetStateFieldData(iField);
838 int numComponents = baseState.NumStateFieldComponents(iField);
840 for(
int iComponent = 0;iComponent <
numComponents;iComponent++){
843 double *k1Buffer = &k1Data[compIndex];
844 double *k2Buffer = &k2Data[compIndex];
845 double *k3Buffer = &k3Data[compIndex];
846 double *k4Buffer = &k4Data[compIndex];
847 double *stateBuffer = &baseData[compIndex];
854 PAPI_read(papiEventSet,counterTicks);
861 (&numDim,&
numPoints,&numPointsX[0],&myInterval[0],
862 &h,k1Buffer,k2Buffer,k3Buffer,k4Buffer,stateBuffer);
868 PAPI_read(papiEventSet,counterTocks);
869 AccumulateCounters(counterTicks,counterTocks,advancerCounters[RKSUMKERNEL]);
879 void GetTimers(
double **timersPtr,
const char ***namesPtr,
unsigned int *numTimers)
881 *timersPtr = advancerTimers;
883 *numTimers = NUMTIMERS;
888 *countersPtr = advancerCounters;
893 myGlobalPtr = &inGlobal;
902 DomainType &simulationDomain(*domainPtr);
905 myThreadId = omp_get_thread_num();
911 for(
int iLocalGrid = 0;iLocalGrid < numGrids;iLocalGrid++){
913 int iGrid = simulationDomain.LocalGridIndex(iLocalGrid);
915 GridType &inGrid(simulationDomain.Grid(iGrid));
917 std::vector<pcpp::IndexIntervalType> &threadPartitionIntervals(inGrid.ThreadPartitionBufferIntervals());
918 std::vector< std::vector<size_t> > &threadFortranIntervals(gridFortranIntervals[iGrid]);
920 std::vector<size_t> &threadFortranInterval(threadFortranIntervals[myThreadId]);
921 threadInterval.
Flatten(threadFortranInterval);
922 std::vector<size_t>::iterator tfIt = threadFortranInterval.begin();
923 while(tfIt != threadFortranInterval.end()){
937 double advancerTimers[NUMTIMERS];
938 long long *advancerCounters[NUMTIMERS];
std::vector< std::vector< StateType > > stageKs
std::vector< std::string > advancerFields
int UnpackStateMessage(StateType &inState, HaloType &inHalo, int messageId, int threadId)
std::vector< int > stateMessageIds
pcpp::ParallelGlobalType * myGlobalPtr
void Flatten(ContainerType &output) const
void const size_t * numPoints
void SetMessageStream(std::ostream &inStream)
subroutine zaxpy(N1, N2, N3, localInterval, a, X, Y, Z)
void AXPY(double a, StateType &X, StateType &Y)
void SetCommunication(bool onoff)
virtual void FunctionExit(const StackType &stackentry)
FunctionExit updates the Stack as well as the Profiler.
void GetCounters(long long ***countersPtr)
void const size_t const size_t * gridSizes
rk4advancer(fixtures::ConfigurationType &inConfig, DomainType &inDomain)
int AXPY(double a, StateType &xState, StateType &yState, StateType &outState, int localGridIndex, int myThreadId)
virtual int AdvanceDomain()
Advances domain, grid, and state by one step.
std::vector< double * > gridTimes
subroutine rk4sum(numDim, numPoints, bufferSize, bufferInterval, h, K1, K2, K3, K4, stateData)
DomainType::GridType GridType
int GetRHS(GridType ¤tGrid, HaloType &gridHalo, StateType &inState, StateType &stateRHS, int myThreadId)
virtual void SetRHS(RHSType &inRHS)
std::vector< std::vector< size_t > > gridSizes
virtual int Configure(fixtures::ConfigurationType &inConfig)
std::vector< size_t > numPointsGrids
virtual int GetStateUpdate(GridType &inGrid, StateType &inState, StateType &stateUpdate)
static double Time()
Simple timer.
virtual void FunctionEntry(const StackType &stackentry)
FunctionEntry updates the Stack as well as the Profiler.
int SetupStateMessage(StateType &inState, HaloType &inHalo)
std::vector< std::vector< StateType > > stageStates
std::vector< RHSType * > rhsHandlers
std::vector< int > threadStage
DomainType::StateType StateType
DomainType::RHSType RHSType
simulation::advancer::base< DomainType > DomainAdvancerType
Main encapsulation of MPI.
void size_t int size_t int size_t int int int int double int int double double *void size_t int size_t int int int int int double int size_t size_t size_t double double *void size_t int size_t int size_t size_t int double int double double *void size_t size_t size_t double * a
virtual int ErrorCheck(fixtures::CommunicatorType &inComm)
std::vector< std::string > GetValueVector(const std::string &key) const
virtual int InterGridExchange()
std::vector< std::vector< int > > gridNeighbors
std::vector< double > stageWeights
std::vector< std::vector< std::vector< size_t > > > gridFortranIntervals
void const size_t const size_t * bufferSizes
static const char * timerNames[]
void GetTimers(double **timersPtr, const char ***namesPtr, unsigned int *numTimers)
int RKSum(int localGridIndex, int myThreadId)
rk4advancer(DomainType &inDomain)
virtual void SetError(const std::string &errorMessage, fixtures::CommunicatorType &inComm)
virtual int InitializeAdvance()
Initialize advance called every time step.
virtual int InitializeAdvancer(DomainType &inDomain, pcpp::ParallelGlobalType &inGlobal, std::ostream &inStream)
Initializes the advancer object.
DomainType::HaloType HaloType
void SetGlobal(pcpp::ParallelGlobalType &inGlobal)
DomainType::OperatorType OperatorType
Simple Block Structured Mesh object.
void size_t int * numComponents
virtual int FinalizeAdvance()
Last call after 1 advance step.
int PackStateMessage(StateType &inState, HaloType &inHalo, int messageId, int threadId)
std::vector< double > updateWeights
void FC_MODULE(euler, flux1d, EULER, FLUX1D)(const int *numDim
std::vector< int > threadGrid
void SetTimers(bool onoff)