/// Collect GVT iteration counts void POSE_sumGVTIterations(void *param, void *msg) { CkReductionMsg *m = (CkReductionMsg *)msg; CkPrintf("Final basic stats: GVT iterations: %d\n", *((int*)m->getData())); delete m; CProxy_pose POSE_Coordinator(POSE_Coordinator_ID); POSE_Coordinator.prepExit(); }
/// /// Feedback main method /// void Main::StellarFeedback(double dTime, double dDelta) { if(verbosity) CkPrintf("Stellar Feedback ... \n"); double startTime = CkWallTimer(); CkReductionMsg *msgFeedback; treeProxy.Feedback(*(param.feedback), dTime, dDelta, CkCallbackResumeThread((void*&)msgFeedback)); double *dFeedback = (double *)msgFeedback->getData(); if(verbosity) { CkPrintf("Feedback totals: mass, energy, metalicity\n"); for(int i = 0; i < NFEEDBACKS; i++){ CkPrintf("feedback %d: %g %g %g\n", i, dFeedback[i*3], dFeedback[i*3 + 1], dFeedback[i*3] != 0.0 ? dFeedback[i*3 + 2]/dFeedback[i*3] : 0.0); } } delete msgFeedback; CkReductionMsg *msgChk; treeProxy.massMetalsEnergyCheck(1, CkCallbackResumeThread((void*&)msgChk)); if(verbosity) CkPrintf("Distribute Stellar Feedback ... "); // Need to build tree since we just did addDelParticle. // treeProxy.buildTree(bucketSize, CkCallbackResumeThread()); DistStellarFeedbackSmoothParams pDSFB(TYPE_GAS, 0, param.csm, dTime, param.dConstGamma, param.feedback); double dfBall2OverSoft2 = 4.0*param.dhMinOverSoft*param.dhMinOverSoft; treeProxy.startSmooth(&pDSFB, 0, param.feedback->nSmoothFeedback, dfBall2OverSoft2, CkCallbackResumeThread()); treeProxy.finishNodeCache(CkCallbackResumeThread()); CkPrintf("Stellar Feedback Calculated, Wallclock %f secs\n", CkWallTimer() - startTime); CkReductionMsg *msgChk2; treeProxy.massMetalsEnergyCheck(0, CkCallbackResumeThread((void*&)msgChk2)); double *dTotals = (double *)msgChk->getData(); double *dTotals2 = (double *)msgChk2->getData(); int i; for(i = 0; i < 5; i++) { std::string labels[5] = {"Mass", "Metals", "Oxygen", "Iron", "Energy"}; if(verbosity > 1) CkPrintf("Total %s: %g\n", labels[i].c_str(), dTotals[i]); if(fabs(dTotals[i] - dTotals2[i]) > 1e-12*(dTotals[i])) { CkError("ERROR: %s not conserved: %.15e != %.15e!\n", labels[i].c_str(), dTotals[i], dTotals2[i]); } } delete msgChk; delete msgChk2; }
void CkArrayReductionMgr::collectAllMessages(){ // if the queue isn't full, but there is at least one message and the // reduction is streamable, do a partial reduction bool partialReduction = count < size && my_msgs.length() > 0 && \ CkReduction::reducerTable[my_msgs.peek()->reducer].streamable; if(count == size || partialReduction) { ARPRINT("[%d] CollectAll messages for %d with %d on %p\n",CkMyNode(),redNo,count,this); CkReductionMsg *result = reduceMessages(); if (partialReduction) { my_msgs.enq(result); return; } result->redNo = redNo; /**keep a count of elements that contributed to the original reduction***/ contributeWithCounter(result,result->gcount); count=0; redNo++; int n=my_futureMsgs.length(); for(int i=0;i<n;i++){ CkReductionMsg *elementMesg = my_futureMsgs.deq(); if(elementMesg->getRedNo() == redNo){ my_msgs.enq(elementMesg); count++; collectAllMessages(); }else{ my_futureMsgs.enq(elementMesg); } } } }
void PsiCache::reportFTime() { CkReduction::statisticsElement stats(total_time); int tuple_size = 2; CkReduction::tupleElement tuple_reduction[] = { CkReduction::tupleElement(sizeof(double), &total_time, CkReduction::max_double), CkReduction::tupleElement(sizeof(CkReduction::statisticsElement), &stats, CkReduction::statistics) }; CkReductionMsg* msg = CkReductionMsg::buildFromTuple(tuple_reduction, tuple_size); msg->setCallback(CkCallback(CkIndex_Controller::reportFTime(NULL), controller_proxy)); contribute(msg); }
/// Exit simulation program after terminus reduction void POSE_prepExit(void *param, void *msg) { CkReductionMsg *m = (CkReductionMsg *)msg; long long *finalBasicStats = ((long long*)m->getData()); CkPrintf("Final basic stats: Commits: %lld Rollbacks: %lld\n", finalBasicStats[0], finalBasicStats[1]); delete m; #ifdef SEQUENTIAL_POSE CProxy_pose POSE_Coordinator(POSE_Coordinator_ID); POSE_Coordinator.prepExit(); #else CProxy_GVT g(TheGVT); g.sumGVTIterationCounts(); #endif }
CkReductionMsg *CkArrayReductionMgr::reduceMessages(void){ #if CMK_BIGSIM_CHARM _TRACE_BG_END_EXECUTE(1); void* _bgParentLog = NULL; _TRACE_BG_BEGIN_EXECUTE_NOMSG("ArrayReduce", &_bgParentLog, 0); #endif CkReductionMsg *ret=NULL; //Look through the vector for a valid reducer, swapping out placeholder messages CkReduction::reducerType r=CkReduction::invalid; int msgs_gcount=0;//Reduced gcount int msgs_nSources=0;//Reduced nSources int msgs_userFlag=-1; CkCallback msgs_callback; CkCallback msgs_secondaryCallback; int i; int nMsgs=0; CkReductionMsg *m; CkReductionMsg **msgArr=new CkReductionMsg*[my_msgs.length()]; bool isMigratableContributor; while(NULL!=(m=my_msgs.deq())) { msgs_gcount+=m->gcount; if (m->sourceFlag!=0) { //This is a real message from an element, not just a placeholder msgArr[nMsgs++]=m; msgs_nSources+=m->nSources(); r=m->reducer; if (!m->callback.isInvalid()) msgs_callback=m->callback; if(!m->secondaryCallback.isInvalid()) msgs_secondaryCallback = m->secondaryCallback; if (m->userFlag!=-1) msgs_userFlag=m->userFlag; isMigratableContributor=m->isMigratableContributor(); #if CMK_BIGSIM_CHARM _TRACE_BG_ADD_BACKWARD_DEP(m->log); #endif } else { //This is just a placeholder message-- replace it delete m; } } if (nMsgs==0||r==CkReduction::invalid) //No valid reducer in the whole vector ret=CkReductionMsg::buildNew(0,NULL); else {//Use the reducer to reduce the messages if(nMsgs == 1){ ret = msgArr[0]; }else{ CkReduction::reducerFn f=CkReduction::reducerTable[r].fn; ret=(*f)(nMsgs,msgArr); } ret->reducer=r; } //Go back through the vector, deleting old messages for (i=0;i<nMsgs;i++) { if (msgArr[i] != ret) delete msgArr[i]; } delete [] msgArr; //Set the message counts ret->redNo=redNo; ret->gcount=msgs_gcount; ret->userFlag=msgs_userFlag; ret->callback=msgs_callback; ret->secondaryCallback = msgs_secondaryCallback; ret->sourceFlag=msgs_nSources; ret->setMigratableContributor(isMigratableContributor); return ret; }