コード例 #1
0
void ActionWithVessel::runAllTasks(){
  if( getExchangeStep() && nactive_tasks!=fullTaskList.size()  ) error("contributors must be unlocked during exchange steps");
  plumed_massert( functions.size()>0, "you must have a call to readVesselKeywords somewhere" );
  unsigned stride=comm.Get_size();
  unsigned rank=comm.Get_rank();
  if(serial){ stride=1; rank=0; }

  // Make sure jobs are done
  if(timers) stopwatch.start("1 Prepare Tasks");
  doJobsRequiredBeforeTaskList();
  if(timers) stopwatch.stop("1 Prepare Tasks");

  // Get number of threads for OpenMP
  unsigned nt=OpenMP::getNumThreads();
  if( nt*stride*10>nactive_tasks) nt=nactive_tasks/stride/10;
  if( nt==0 ) nt=1;

  // Get size for buffer
  unsigned bsize=0, bufsize=getSizeOfBuffer( bsize ); 
  // Clear buffer
  buffer.assign( buffer.size(), 0.0 );
  // Switch off calculation of derivatives in main loop
  if( dertime_can_be_off ) dertime=false;

  // std::vector<unsigned> der_list;
  // if( mydata ) der_list.resize( mydata->getSizeOfDerivativeList(), 0 ); 

  // Build storage stuff for loop
  // std::vector<double> buffer( bufsize, 0.0 );

  if(timers) stopwatch.start("2 Loop over tasks");
#pragma omp parallel num_threads(nt)
{
  std::vector<double> omp_buffer;
  if( nt>1 ) omp_buffer.resize( bufsize, 0.0 );
  MultiValue myvals( getNumberOfQuantities(), getNumberOfDerivatives() );
  MultiValue bvals( getNumberOfQuantities(), getNumberOfDerivatives() );
  myvals.clearAll(); bvals.clearAll();
 
#pragma omp for nowait
  for(unsigned i=rank;i<nactive_tasks;i+=stride){
      // Calculate the stuff in the loop for this action
      performTask( indexOfTaskInFullList[i], partialTaskList[i], myvals );
      // Weight should be between zero and one
      plumed_dbg_assert( myvals.get(0)>=0 && myvals.get(0)<=1.0 );

      // Check for conditions that allow us to just to skip the calculation
      // the condition is that the weight of the contribution is low 
      // N.B. Here weights are assumed to be between zero and one
      if( myvals.get(0)<tolerance ){
         // Deactivate task if it is less than the neighbor list tolerance
         if( myvals.get(0)<nl_tolerance && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] );
         // Clear the derivatives
         myvals.clearAll();
         continue;
      }

      // Now calculate all the functions
      // If the contribution of this quantity is very small at neighbour list time ignore it
      // untill next neighbour list time
      if( nt>1 ){
          if( !calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, omp_buffer, der_list ) && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] );
      } else {
          if( !calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, buffer, der_list ) && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] );
      }

      // Clear the value
      myvals.clearAll();
  }
#pragma omp critical
  if(nt>1) for(unsigned i=0;i<bufsize;++i) buffer[i]+=omp_buffer[i];
}
  if(timers) stopwatch.stop("2 Loop over tasks");
  // Turn back on derivative calculation
  dertime=true;

  if(timers) stopwatch.start("3 MPI gather");
  // MPI Gather everything
  if( !serial && buffer.size()>0 ) comm.Sum( buffer );
  // MPI Gather index stores
  if( mydata && !lowmem && !noderiv ){ 
     comm.Sum( der_list ); mydata->setActiveValsAndDerivatives( der_list ); 
  }
  // Update the elements that are makign contributions to the sum here
  // this causes problems if we do it in prepare
  if( !serial && contributorsAreUnlocked ) comm.Sum( taskFlags );
  if(timers) stopwatch.stop("3 MPI gather");

  if(timers) stopwatch.start("4 Finishing computations");
  finishComputations( buffer );
  if(timers) stopwatch.stop("4 Finishing computations");
}
コード例 #2
0
ファイル: CbcpM.cpp プロジェクト: cran/bcp
MCMCStepSeq pass(MCMCStepSeq &step, HelperVariables &helpers, Params &params)
{

  int i, j, cp;

  int bsize1, bsize2, bsize3;
  double tmp;
  DoubleVec bmean1(params.kk, 0);
  DoubleVec bmean2(params.kk, 0);
  DoubleVec bmean3(params.kk, 0);
  double bZ1, bZ2, bZ3;

  IntVec bvals(2);
  DoubleVec Wvals(2);
  DoubleVec Bvals(2);

  DoubleVec bmeanlast(params.kk);
  double bZlast = 0;

  // this is used to reference the current block in the MCMCStep we came in with
  int prevblock = 0;

  // this is used to reference the current MCMCStep we build from scratch
  MCMCStepSeq stepnew(step);
  int currblock = 0;

  // some other variables to denote stuff in current block and previous block
  // Note that "last" refers to the immediately left-adjacent block
  // whereas "prev" refers to the same block in the variable step
  double thisblockZ = step.bZ[0];
  int thisbend = step.bend[0];

  double lastblockZ = 0;
  int lastbend = -1; // this is simply a notational convenience

  // start the loop
  for (i = 0; i < params.nn - 1; i++) {
    if (i == step.bend[prevblock]) {
      // we're at an old change point, so we need to refresh "this" to be the
      // immediately following block
      lastblockZ = thisblockZ;
      prevblock++;

      thisbend = step.bend[prevblock];
      thisblockZ = step.bZ[prevblock];
    }
    /****
     * consider merging blocks if currently a change point
     */
    bvals[0] = stepnew.b;
    if (step.rho[i] == 0) { // not a change point at the moment
      Bvals[0] = stepnew.B;
      Wvals[0] = stepnew.W;
    } else { // it is a change point, so let's try removing the change point
      bvals[0]--;
      tmp = thisblockZ + lastblockZ;
      bZ3 = 0;
      if (lastbend > -1) {
        bsize3 = helpers.cumksize[thisbend] - helpers.cumksize[lastbend];
        for (j = 0; j < params.kk; j++) {
          bmean3[j] = (helpers.cumymat[j][thisbend] - helpers.cumymat[j][lastbend]) / bsize3;
          bZ3 += pow(bmean3[j], 2) * bsize3;
        }
      } else {
        bsize3 = helpers.cumksize[thisbend];
        for (j = 0; j < params.kk; j++) {
          bmean3[j] = helpers.cumymat[j][thisbend] / bsize3;
          bZ3 += pow(bmean3[j], 2) * bsize3;
        }
      }
      if (params.kk == 1 && bvals[0] == 1) Bvals[0] = 0; // force this to avoid rounding errs
      else
        Bvals[0] = stepnew.B - tmp + bZ3;
      Wvals[0] = stepnew.W + tmp - bZ3;
    }


    /****
     * consider breaking blocks if not a change point
     */
    bvals[1] = stepnew.b;
    if (step.rho[i] == 1) {
      Bvals[1] = stepnew.B;
      Wvals[1] = stepnew.W;
    } else {
      bZ1 = 0;
      bZ2 = 0;
      bvals[1]++;
      bsize2 = helpers.cumksize[thisbend] - helpers.cumksize[i];

      if (lastbend > -1)
        bsize1 = helpers.cumksize[i] - helpers.cumksize[lastbend];
      else
        bsize1 = helpers.cumksize[i];
      tmp = thisblockZ;
      for (j = 0; j < params.kk; j++) {
        bmean2[j] = (helpers.cumymat[j][thisbend] - helpers.cumymat[j][i]) / bsize2;
        if (lastbend > -1) {
          bmean1[j] = (helpers.cumymat[j][i] - helpers.cumymat[j][lastbend]) / bsize1;
        } else {
          bmean1[j] = helpers.cumymat[j][i] / bsize1;
        }
        bZ1 += pow(bmean1[j], 2) * bsize1;
        bZ2 += pow(bmean2[j], 2) * bsize2;
      }
      Bvals[1] = stepnew.B - tmp + bZ1 + bZ2;
      Wvals[1] = stepnew.W + tmp - bZ1 - bZ2;
    }

    // if (i == 4122) return(stepnew);
    double p = getprob(Bvals[0], Bvals[1], Wvals[0], Wvals[1], bvals[0], params);
    // do the sampling and then updates
    double myrand = Rf_runif(0.0, 1.0);

    if (myrand < p) {
      cp = 1;
    } else {
      cp = 0;
    }
    // Rprintf("i:%d  p=%0.4f, myrand=%0.2f, cp=%d\n", i, p, myrand, cp);

    stepnew.B = Bvals[cp];
    stepnew.W = Wvals[cp];
    stepnew.b = bvals[cp];

    if (cp != step.rho[i]) { // we modified the change point status
      if (cp == 0) {
        // removed a change point
        // update last block's stuff since the last block is now further back
        thisblockZ = bZ3;
        if (currblock > 0) {
          lastbend = stepnew.bend[currblock - 1];
          lastblockZ = stepnew.bZ[currblock - 1];
        } else {
          lastblockZ = 0;
          lastbend = -1; // this is simply a notational convenience
        }
      } else { // added a change point
        thisblockZ = bZ2;
        lastblockZ = bZ1;
      }
    }
    stepnew.rho.push_back(cp);

    if (stepnew.rho[i] == 1) {
      if (step.rho[i] == 1) { // never calculated these quantities yet; do it now
        lastblockZ = 0;

        if (lastbend > -1)
          bsize1 = helpers.cumksize[i] - helpers.cumksize[lastbend];
        else
          bsize1 = helpers.cumksize[i];
        for (j = 0; j < params.kk; j++) {
          if (lastbend > -1) {
            bmean1[j] = (helpers.cumymat[j][i] - helpers.cumymat[j][lastbend]) / bsize1;
          } else {
            bmean1[j] = helpers.cumymat[j][i] / bsize1;
          }
          lastblockZ += pow(bmean1[j], 2) * bsize1;
        }
      }
      // we've added a change point, so we want to record some stuff
      stepnew.bsize.push_back(bsize1);
      stepnew.bend.push_back(i);
      stepnew.bmean.push_back(bmean1);
      stepnew.bZ.push_back(lastblockZ);
      currblock++;
      lastbend = i;

    }
  }
  // done with a full pass, now let's add info on the final block
  if (lastbend > -1)
    stepnew.bsize.push_back(params.nn2 - helpers.cumksize[lastbend]);
  else
    stepnew.bsize.push_back(params.nn2);
  for (j = 0; j < params.kk; j++) {
    if (lastbend > -1) {
      bmeanlast[j] = (helpers.cumymat[j][params.nn - 1] - helpers.cumymat[j][lastbend]) / stepnew.bsize[currblock];
    } else {
      bmeanlast[j] = helpers.cumymat[j][params.nn - 1] / params.nn2;
    }
    bZlast += pow(bmeanlast[j], 2) * stepnew.bsize[currblock];
  }
  stepnew.bmean.push_back(bmeanlast);
  stepnew.bZ.push_back(bZlast);
  stepnew.bend.push_back(params.nn - 1);
  stepnew.rho.push_back(1);
  return stepnew;
}