int MapReduceKernelConn::initialize(const char * name, HyPerCol * hc) {
   int status = HyPerConn::initialize(name, hc);
   // if (status==PV_SUCCESS) status = setMovieLayerName();
   InterColComm *icComm = parent->icCommunicator();
   int rootproc = 0;
   int file_count = 0;
   PV_Stream * dWeightstream = pvp_open_read_file(this->dWeightsListName,
           icComm);
   if ((dWeightstream == NULL) && (icComm->commRank() == rootproc)) {
       fprintf(stderr,
             "MapReduceKernelConn::initialize: Cannot open list of dWeight files \"%s\".  Exiting.\n",
             this->dWeightsListName); // CHECK THIS! // CHECK THIS! this->dWeightsListName was filename but filename is no more
       exit(EXIT_FAILURE);
   } // dWeightstream == NULL

   if (icComm->commRank() == rootproc) {
      for (file_count = 0; file_count < num_dWeightFiles; file_count++) {
         /*
         for (int i_char = 0; i_char < PV_PATH_MAX; i_char++) {
            dWeightsList[file_count][i_char] = 0;
         }
         */

         char * fgetsstatus = fgets(dWeightsList[file_count], PV_PATH_MAX, dWeightstream->fp);
         if (fgetsstatus == NULL) {
            bool endoffile = feof(dWeightstream->fp) != 0;
            if (endoffile) {
               fprintf(stderr,
                       "MapReduceKernelConn::initialize: "
                               "File of weight files \"%s\" reached end of file before all %d weight files were read.  "
                               "Exiting.\n", dWeightstream->name, num_dWeightFiles); // CHECK THIS! dWeightstream->name was filename but filename is no more
               exit(EXIT_FAILURE);
            }
            else {
               int error = ferror(dWeightstream->fp);
               assert(error);
               fprintf(stderr,
                     "MapReduceKernelConn::initialize: File of weight files error reading:%s.  Exiting.\n", strerror(error));
               exit(error);
            }
         }
         else {
            // Remove linefeed from end of string
            dWeightsList[file_count][PV_PATH_MAX - 1] = '\0';
            int len = strlen(dWeightsList[file_count]);
            if (len > 1) {
               if (dWeightsList[file_count][len - 1] == '\n') {
                  dWeightsList[file_count][len - 1] = '\0';
               }
            }
         } // fgetsstatus == NULL
     } // file_count
     this->dWeightsFilename = strdup(dWeightsList[dWeightFileIndex]);
     std::cout << "dWeightFile[" << dWeightFileIndex << "] = "
           << dWeightsList[dWeightFileIndex] << std::endl;
   } // commRank() == rootproc
   return status;
}
Beispiel #2
0
int InitWeights::readCombinedWeightFiles(PVPatch *** patches, pvwdata_t ** dataStart,int numPatches, const char * fileOfWeightFiles, double * timef) {
   InterColComm *icComm = callingConn->getParent()->icCommunicator();
   int numArbors = callingConn->numberOfAxonalArborLists();
   const PVLayerLoc *preLoc = callingConn->preSynapticLayer()->getLayerLoc();
   double timed;
   int rootproc = 0;
   int max_weight_files = 1;  // arbitrary limit...
   int num_weight_files = weightParams->getNumWeightFiles();
   int file_count=0;
   PV_Stream * weightstream = pvp_open_read_file(fileOfWeightFiles, icComm);
   if ((weightstream == NULL) && (icComm->commRank() == rootproc) ){
      pvError().printf("Cannot open file of weight files \"%s\".  Exiting.\n", fileOfWeightFiles);
   }

   char weightsfilename[PV_PATH_MAX];
   while( file_count < num_weight_files ) {
      if( icComm->commRank() == rootproc ) {
         char * fgetsstatus = fgets(weightsfilename, PV_PATH_MAX, weightstream->fp);
         if( fgetsstatus == NULL ) {
            bool endoffile = feof(weightstream->fp)!=0;
            if( endoffile ) {
               pvError().printf("File of weight files \"%s\" reached end of file before all %d weight files were read.  Exiting.\n", fileOfWeightFiles, num_weight_files);
            }
            else {
               int error = ferror(weightstream->fp);
               assert(error);
               pvError().printf("File of weight files: error %d while reading.  Exiting.\n", error);
            }
         }
         else {
            // Remove linefeed from end of string
            weightsfilename[PV_PATH_MAX-1] = '\0';
            int len = strlen(weightsfilename);
            if (len > 1) {
               if (weightsfilename[len-1] == '\n') {
                  weightsfilename[len-1] = '\0';
               }
            }
         }
      } // commRank() == rootproc
      int filetype, datatype;
      int numParams = NUM_BIN_PARAMS+NUM_WGT_EXTRA_PARAMS;
      int params[NUM_BIN_PARAMS+NUM_WGT_EXTRA_PARAMS];
      pvp_read_header(weightsfilename, icComm, &timed, &filetype, &datatype, params, &numParams);
      const int nxp = callingConn->xPatchSize();
      const int nyp = callingConn->yPatchSize();
      const int nfp = callingConn->fPatchSize();
      int status = PV::readWeights(patches, dataStart, numArbors, numPatches, nxp, nyp, nfp, weightsfilename, icComm, &timed, preLoc);
      if (status != PV_SUCCESS) {
         pvError().printf("PV::InitWeights::readWeights: problem reading arbor file %s, SHUTTING DOWN\n", weightsfilename);
      }
      file_count += 1;
   } // file_count < num_weight_files

   return PV_SUCCESS;
}
int ArborTestProbe::outputState(double timed)
{
   int status = StatsProbe::outputState(timed);
   InterColComm * icComm = getTargetLayer()->getParent()->icCommunicator();
   const int rcvProc = 0;
   if( icComm->commRank() != rcvProc ) {
      return 0;
   }
   for(int b = 0; b < getParent()->getNBatch(); b++){
      if(timed==1.0f){
         assert((avg[b]>0.2499)&&(avg[b]<0.2501));
      }
      else if(timed==2.0f){
         assert((avg[b]>0.4999)&&(avg[b]<0.5001));
      }
      else if(timed==3.0f){
         assert((avg[b]>0.7499)&&(avg[b]<0.7501));
      }
      else if(timed>3.0f){
         assert((fMin[b]>0.9999)&&(fMin[b]<1.001));
         assert((fMax[b]>0.9999)&&(fMax[b]<1.001));
         assert((avg[b]>0.9999)&&(avg[b]<1.001));
      }
   }

	return status;
}
Beispiel #4
0
int KernelProbe::outputState(double timed) {
   InterColComm * icComm = parent->icCommunicator();
   const int rank = icComm->commRank();
   if( rank != 0 ) return PV_SUCCESS;
   assert(getTargetConn()!=NULL);
   int nxp = getTargetHyPerConn()->xPatchSize();
   int nyp = getTargetHyPerConn()->yPatchSize();
   int nfp = getTargetHyPerConn()->fPatchSize();
   int patchSize = nxp*nyp*nfp;

   const pvwdata_t * wdata = getTargetHyPerConn()->get_wDataStart(arborID)+patchSize*kernelIndex;
   const pvwdata_t * dwdata = outputPlasticIncr ?
         getTargetHyPerConn()->get_dwDataStart(arborID)+patchSize*kernelIndex : NULL;
   fprintf(outputstream->fp, "Time %f, Conn \"%s\", nxp=%d, nyp=%d, nfp=%d\n",
           timed, getTargetConn()->getName(),nxp, nyp, nfp);
   for(int f=0; f<nfp; f++) {
      for(int y=0; y<nyp; y++) {
         for(int x=0; x<nxp; x++) {
            int k = kIndex(x,y,f,nxp,nyp,nfp);
            fprintf(outputstream->fp, "    x=%d, y=%d, f=%d (index %d):", x, y, f, k);
            if(getOutputWeights()) {
               fprintf(outputstream->fp, "  weight=%f", (float)wdata[k]);
            }
            if(getOutputPlasticIncr()) {
               fprintf(outputstream->fp, "  dw=%f", (float)dwdata[k]);
            }
            fprintf(outputstream->fp,"\n");
         }
      }
   }

   return PV_SUCCESS;
}
/**
 * @time
 * @l
 */
int DatastoreDelayTestProbe::outputState(double timed) {
   HyPerLayer * l = getTargetLayer();
   InterColComm * icComm = l->getParent()->icCommunicator();
   const int rcvProc = 0;
   if( icComm->commRank() != rcvProc ) {
      return PV_SUCCESS;
   }
   int status = PV_SUCCESS;
   int numDelayLevels = l->getParent()->getLayer(0)->getNumDelayLevels();
   pvdata_t correctValue = numDelayLevels*(numDelayLevels+1)/2;
   if( timed >= numDelayLevels+2 ) {
      pvdata_t * V = l->getV();
      for( int k=0; k<l->getNumNeuronsAllBatches(); k++ ) {
         if( V[k] != correctValue ) {
            fprintf(outputstream->fp, "Layer \"%s\": timef = %f, neuron %d: value is %f instead of %d\n", l->getName(), timed, k, V[k], (int) correctValue);
            status = PV_FAILURE;
         }
      }
      if( status == PV_SUCCESS) {
         fprintf(outputstream->fp, "Layer \"%s\": timef = %f, all neurons have correct value %d\n", l->getName(), timed, (int) correctValue);
      }
   }
   assert(status == PV_SUCCESS);
   return PV_SUCCESS;
}
PlasticConnTestProbe::~PlasticConnTestProbe() {
   InterColComm * icComm = getParent()->icCommunicator();
   if( icComm->commRank() == 0) {
      if( !errorPresent ) {
         outputStream->printf("No errors detected\n");
      }
   }
}
Beispiel #7
0
/**
 * - Update the image buffers
 * - If the time is a multiple of biasChangetime then the position of the bias (biasX, biasY) changes.
 * - With probability persistenceProb the offset position (offsetX, offsetY) remains unchanged.
 * - Otherwise, with probability (1-persistenceProb) the offset position performs a random walk
 *   around the bias position (biasX, biasY).
 *
 * - If the time is a multiple of displayPeriod then load the next image.
 * - If nf=1 then the image is converted to grayscale during the call to read(filename, offsetX, offsetY).
 *   If nf>1 then the image is loaded with color information preserved.
 * - Return true if buffers have changed
 */
bool Movie::updateImage(double time, double dt)
{
   if( jitterFlag ) {
      jitter();
   } // jitterFlag

   InterColComm * icComm = getParent()->icCommunicator();

      //TODO: Fix movie layer to take with batches. This is commented out for compile
      //if(!flipOnTimescaleError && (parent->getTimeScale() > 0 && parent->getTimeScale() < parent->getTimeScaleMin())){
      //   if (parent->icCommunicator()->commRank()==0) {
      //      std::cout << "timeScale of " << parent->getTimeScale() << " is less than timeScaleMin of " << parent->getTimeScaleMin() << ", Movie is keeping the same frame\n";
      //   }
      //}
      //else{
         //Only do this if it's not the first update timestep
         //The timestep number is (time - startTime)/(width of timestep), with allowance for roundoff.
         //But if we're using adaptive timesteps, the dt passed as a function argument is not the correct (width of timestep).  
      if(fabs(time - (parent->getStartTime() + parent->getDeltaTime())) > (parent->getDeltaTime()/2)){
         int status = getFrame(time, dt);
         assert(status == PV_SUCCESS);
      }
      
      


      //nextDisplayTime removed, now using nextUpdateTime in HyPerLayer
      //while (time >= nextDisplayTime) {
      //   nextDisplayTime += displayPeriod;
      //}
      //Set frame number (member variable in Image)
      
      //Write to timestamp file here when updated
      if( icComm->commRank()==0 ) {
          //Only write if the parameter is set
          if(timestampFile){
             std::ostringstream outStrStream;
             outStrStream.precision(15);
             int kb0 = getLayerLoc()->kb0;
             for(int b = 0; b < parent->getNBatch(); b++){
                outStrStream << time << "," << b+kb0 << "," << frameNumbers[b] << "," << framePath[b] << "\n";
             }

             size_t len = outStrStream.str().length();
             int status = PV_fwrite(outStrStream.str().c_str(), sizeof(char), len, timestampFile)==len ? PV_SUCCESS : PV_FAILURE;
             if (status != PV_SUCCESS) {
                fprintf(stderr, "%s \"%s\" error: Movie::updateState failed to write to timestamp file.\n", getKeyword(), name);
                exit(EXIT_FAILURE);
             }
             //Flush buffer
             fflush(timestampFile->fp);
          }
      }
   //} // randomMovie

   return true;
}
Beispiel #8
0
int InitWeights::readListOfArborFiles(PVPatch *** patches, pvwdata_t ** dataStart, int numPatches, const char * listOfArborsFilename, double * timef) {
   int arbor=0;
   InterColComm *icComm = callingConn->getParent()->icCommunicator();
   int numArbors = callingConn->numberOfAxonalArborLists();
   const PVLayerLoc *preLoc = callingConn->preSynapticLayer()->getLayerLoc();
   double timed;
   PV_Stream * arborstream = pvp_open_read_file(listOfArborsFilename, icComm);

   int rootproc = 0;
   char arborfilename[PV_PATH_MAX];
   while( arbor < callingConn->numberOfAxonalArborLists() ) {
      if( icComm->commRank() == rootproc ) {
         char * fgetsstatus = fgets(arborfilename, PV_PATH_MAX, arborstream->fp);
         if( fgetsstatus == NULL ) {
            bool endoffile = feof(arborstream->fp)!=0;
            if( endoffile ) {
               fprintf(stderr, "File of arbor files \"%s\" reached end of file before all %d arbors were read.  Exiting.\n", listOfArborsFilename, numArbors);
               exit(EXIT_FAILURE);
            }
            else {
               int error = ferror(arborstream->fp);
               assert(error);
               fprintf(stderr, "File of arbor files: error %d while reading.  Exiting.\n", error);
               exit(error);
            }
         }
         else {
            // Remove linefeed from end of string
            arborfilename[PV_PATH_MAX-1] = '\0';
            int len = strlen(arborfilename);
            if (len > 1) {
               if (arborfilename[len-1] == '\n') {
                  arborfilename[len-1] = '\0';
               }
            }
         }
      } // commRank() == rootproc
      int filetype, datatype;
      int numParams = NUM_BIN_PARAMS+NUM_WGT_EXTRA_PARAMS;
      int params[NUM_BIN_PARAMS+NUM_WGT_EXTRA_PARAMS];
      pvp_read_header(arborfilename, icComm, &timed, &filetype, &datatype, params, &numParams);
      int thisfilearbors = params[INDEX_NBANDS];
      const int nxp = callingConn->xPatchSize();
      const int nyp = callingConn->yPatchSize();
      const int nfp = callingConn->fPatchSize();

      int status = PV::readWeights(patches ? &patches[arbor] : NULL, &dataStart[arbor], numArbors-arbor, numPatches, nxp, nyp, nfp, arborfilename, icComm, &timed, preLoc);
      if (status != PV_SUCCESS) {
         fprintf(stderr, "PV::InitWeights::readWeights: problem reading arbor file %s, SHUTTING DOWN\n", arborfilename);
         exit(EXIT_FAILURE);
      }
      arbor += thisfilearbors;
   }  // while
   pvp_close_file(arborstream, icComm);
   return PV_SUCCESS;
}
Beispiel #9
0
int LCALIFLayer::checkpointWrite(const char * cpDir) {
   int status = LIFGap::checkpointWrite(cpDir);
   InterColComm * icComm = parent->icCommunicator();
   char basepath[PV_PATH_MAX];
   char filename[PV_PATH_MAX];
   int lenbase = snprintf(basepath, PV_PATH_MAX, "%s/%s", cpDir, name);
   if (lenbase+strlen("_integratedSpikeCount.pvp") >= PV_PATH_MAX) { // currently _integratedSpikeCount.pvp is the longest suffix needed
      if (icComm->commRank()==0) {
         fprintf(stderr, "LCALIFLayer::checkpointWrite error in layer \"%s\".  Base pathname \"%s/%s_\" too long.\n", name, cpDir, name);
      }
      abort();
   }
   double timed = (double) parent->simulationTime();
   int chars_needed = snprintf(filename, PV_PATH_MAX, "%s_integratedSpikeCount.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &integratedSpikeCount, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_Vadpt.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &Vadpt, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_Vattained.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &Vattained, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_Vmeminf.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &Vmeminf, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_G_Norm.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &G_Norm, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_GSynExcEffective.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &GSynExcEffective, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_GSynInhEffective.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &GSynInhEffective, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_excitatoryNoise.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &excitatoryNoise, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_inhibitoryNoise.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &inhibitoryNoise, 1, /*extended*/false, getLayerLoc());

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s_inhibNoiseB.pvp", basepath);
   assert(chars_needed < PV_PATH_MAX);
   writeBufferFile(filename, icComm, timed, &inhibNoiseB, 1, /*extended*/false, getLayerLoc());

   return status;
}
Beispiel #10
0
int customexit(HyPerCol * hc, int argc, char ** argv) {
   pvadata_t correctvalue = 0.5f;
   pvadata_t tolerance = 1.0e-7f;

   if (hc->columnId()==0) {
      pvInfo().printf("Checking whether input layer has all values equal to %f ...\n", correctvalue);
   }
   HyPerLayer * inputlayer = hc->getLayerFromName("input");
   assert(inputlayer);
   PVLayerLoc const * loc = inputlayer->getLayerLoc();
   assert(loc->nf==1);
   const int numNeurons = inputlayer->getNumNeurons();
   assert(numNeurons>0);
   int status = PV_SUCCESS;

   int numExtended = inputlayer->getNumExtended();
   InterColComm * icComm = hc->icCommunicator();
   pvadata_t * layerData = (pvadata_t *) icComm->publisherStore(inputlayer->getLayerId())->buffer(LOCAL);
   int rootproc = 0;
   if (icComm->commRank()==rootproc) {
      pvadata_t * databuffer = (pvadata_t *) malloc(numExtended*sizeof(pvadata_t));
      assert(databuffer);
      for (int proc=0; proc<icComm->commSize(); proc++) {
         if (proc==rootproc) {
            memcpy(databuffer, layerData, numExtended*sizeof(pvadata_t));
         }
         else {
            MPI_Recv(databuffer, numExtended*sizeof(pvadata_t),MPI_BYTE,proc,15,icComm->communicator(), MPI_STATUS_IGNORE);
         }
         // At this point, databuffer on rank 0 should contain the extended input layer on rank proc
         for (int k=0; k<numNeurons; k++) {
            int kExt = kIndexExtended(k,loc->nx,loc->ny,loc->nf,loc->halo.lt,loc->halo.rt,loc->halo.dn,loc->halo.up);
            pvadata_t value = databuffer[kExt];
            if (fabs(value-correctvalue)>=tolerance) {
               pvErrorNoExit().printf("Rank %d, restricted index %d, extended index %d, value is %f instead of %f\n",
                     proc, k, kExt, value, correctvalue);
               status = PV_FAILURE;
            }
         }
      }
      free(databuffer);
      if (status == PV_SUCCESS) {
         pvInfo().printf("%s succeeded.\n", argv[0]);
      }
      else {
         pvError().printf("%s failed.\n", argv[0]);
      }
   }
   else {
      MPI_Send(layerData,numExtended*sizeof(pvadata_t),MPI_BYTE,rootproc,15,icComm->communicator());
   }
   MPI_Barrier(icComm->communicator());
   return status;
}
Beispiel #11
0
// advance by n_skip lines through file of filenames, always advancing at least one line
const char * Movie::getNextFileName(int n_skip, int batchIdx) {
   InterColComm * icComm = getParent()->icCommunicator();
   assert(icComm->commRank() == 0);
   const char* outFilename = NULL;
   int numskip = n_skip < 1 ? 1 : n_skip;
   for (int i_skip = 0; i_skip < numskip; i_skip++){
      outFilename = advanceFileName(batchIdx);
   }
   if (echoFramePathnameFlag){
      printf("%f, %d: %s\n", parent->simulationTime(), batchIdx, outFilename);
   }
   return outFilename;
}
/**
 * @timef
 */
int PlasticConnTestProbe::outputState(double timed) {
   HyPerConn * c = getTargetHyPerConn();
   InterColComm * icComm = c->getParent()->icCommunicator();
   const int rcvProc = 0;
   if( icComm->commRank() != rcvProc ) {
      return PV_SUCCESS;
   }
   assert(getTargetConn()!=NULL);
   outputStream->printf("    Time %f, connection \"%s\":\n", timed, getTargetName());
   const pvwdata_t * w = c->get_wDataHead(getArbor(), getKernelIndex());
   const pvdata_t * dw = c->get_dwDataHead(getArbor(), getKernelIndex());
   if( getOutputPlasticIncr() && dw == NULL ) {
      pvError().printf("PlasticConnTestProbe \"%s\": connection \"%s\" has dKernelData(%d,%d) set to null.\n", getName(), getTargetName(), getKernelIndex(), getArbor());
   }
   int nxp = c->xPatchSize();
   int nyp = c->yPatchSize();
   int nfp = c->fPatchSize();
   int status = PV_SUCCESS;
   for( int k=0; k<nxp*nyp*nfp; k++ ) {
      int x=kxPos(k,nxp,nyp,nfp);
      int wx = (nxp-1)/2 - x; // assumes connection is one-to-one
      if(getOutputWeights()) {
         pvdata_t wCorrect = timed*wx;
         pvdata_t wObserved = w[k];
         if( fabs( ((double) (wObserved - wCorrect))/timed ) > 1e-4 ) {
            int y=kyPos(k,nxp,nyp,nfp);
            int f=featureIndex(k,nxp,nyp,nfp);
            outputStream->printf("        index %d (x=%d, y=%d, f=%d: w = %f, should be %f\n", k, x, y, f, wObserved, wCorrect);
         }
      }
      if(timed > 0 && getOutputPlasticIncr() && dw != NULL) {
         pvdata_t dwCorrect = wx;
         pvdata_t dwObserved = dw[k];
         if( dwObserved != dwCorrect ) {
            int y=kyPos(k,nxp,nyp,nfp);
            int f=featureIndex(k,nxp,nyp,nfp);
            outputStream->printf("        index %d (x=%d, y=%d, f=%d: dw = %f, should be %f\n", k, x, y, f, dwObserved, dwCorrect);
         }
      }
   }
   assert(status==PV_SUCCESS);
   if( status == PV_SUCCESS ) {
      if (getOutputWeights())     { outputStream->printf("        All weights are correct.\n"); }
      if (getOutputPlasticIncr()) { outputStream->printf("        All plastic increments are correct.\n"); }
   }
   if(getOutputPatchIndices()) {
      patchIndices(c);
   }

   return PV_SUCCESS;
}
Beispiel #13
0
bool DisparityMovie::updateImage(double timef, double dt){
   InterColComm * icComm = getParent()->icCommunicator();
   assert(!readPvpFile);

   if(fabs(timef - (parent->getStartTime() + parent->getDeltaTime())) > (parent->getDeltaTime()/2)){
      //If disparity is over numDisparity, read new image and reset index
      if(disparityIndex >= numDisparity - 1){
         if (filename != NULL) free(filename);
         filename = strdup(getNextFileName(skipFrameIndex));
         disparityIndex = 0;
         frameCount++;
      }
      else{
         disparityIndex++;
      }
   }
   assert(filename != NULL);

   //Set frame number (member variable in Image)
   int newOffsetX;
   if((frameCount + frameOffset) % 2 == 0){
      newOffsetX = this->offsets[0];
   }
   else{
      newOffsetX = this->offsets[0] + (disparityIndex * dPixelDisparity);
   }
   int status = readImage(filename, newOffsetX, this->offsets[1], this->offsetAnchor);
   if( status != PV_SUCCESS ) {
      fprintf(stderr, "Movie %s: Error reading file \"%s\"\n", name, filename);
      abort();
   }
   //Write to timestamp file here when updated
   if( icComm->commRank()==0 ) {
      //Only write if the parameter is set
      if(timestampFile){
         std::ostringstream outStrStream;
         outStrStream.precision(15);
         outStrStream << frameNumber << "," << timef << "," << filename << "\n";
         size_t len = outStrStream.str().length();
         int status = PV_fwrite(outStrStream.str().c_str(), sizeof(char), len, timestampFile)==len ? PV_SUCCESS : PV_FAILURE;
         if (status != PV_SUCCESS) {
            fprintf(stderr, "%s \"%s\" error: Movie::updateState failed to write to timestamp file.\n", parent->parameters()->groupKeywordFromName(name), name);
            exit(EXIT_FAILURE);
         }
         //Flush buffer
         fflush(timestampFile->fp);
      }
   }
   return true;
}
/**
 * @timef
 */
int MomentumConnTestProbe::outputState(double timed) {
   HyPerConn * c = getTargetHyPerConn();
   InterColComm * icComm = c->getParent()->icCommunicator();
   const int rcvProc = 0;
   if( icComm->commRank() != rcvProc ) {
      return PV_SUCCESS;
   }
   assert(getTargetConn()!=NULL);
   FILE * fp = getStream()->fp;
   fprintf(fp, "    Time %f, connection \"%s\":\n", timed, getTargetName());
   const pvwdata_t * w = c->get_wDataHead(getArbor(), getKernelIndex());
   const pvdata_t * dw = c->get_dwDataHead(getArbor(), getKernelIndex());
   if( getOutputPlasticIncr() && dw == NULL ) {
      fprintf(stderr, "MomentumConnTestProbe \"%s\": connection \"%s\" has dKernelData(%d,%d) set to null.\n", getName(), getTargetName(), getKernelIndex(), getArbor());
      assert(false);
   }
   int nxp = c->xPatchSize();
   int nyp = c->yPatchSize();
   int nfp = c->fPatchSize();
   int status = PV_SUCCESS;
   for( int k=0; k<nxp*nyp*nfp; k++ ) {
      pvdata_t wObserved = w[k];
      //Pulse happens at time 3
      pvdata_t wCorrect;

      if(timed < 3){
         wCorrect = 0;
      }
      else{
         if(isViscosity){
            wCorrect = 1;
            for(int i = 0; i < (timed - 3); i++){
               wCorrect += exp(-(2*(i+1)));
            }
         }
         else{
            wCorrect = 2 - pow(2, -(timed - 3));
         }
      }

      if( fabs( ((double) (wObserved - wCorrect))/timed ) > 1e-4 ) {
         int y=kyPos(k,nxp,nyp,nfp);
         int f=featureIndex(k,nxp,nyp,nfp);
         fprintf(fp, "        w = %f, should be %f\n", wObserved, wCorrect);
         exit(-1);
      }
   }

   return PV_SUCCESS;
}
int BatchSweepTestProbe::outputState(double timed) {
   int status = StatsProbe::outputState(timed);
   InterColComm * icComm = getTargetLayer()->getParent()->icCommunicator();
   const int rcvProc = 0;
   if( icComm->commRank() != rcvProc ) {
      return 0;
   }
   for(int b = 0; b < parent->getNBatch(); b++){
      if (timed >= 3.0 ) {
         assert(fabs(expectedSum - sum[b])<1e-6);
         assert(fabs(expectedMin - fMin[b])<1e-6);
         assert(fabs(expectedMax - fMax[b])<1e-6);
      }
   }
   return status;
}
int InitWeightTestProbe::outputState(double timed)
{
   int status = StatsProbe::outputState(timed);
   InterColComm * icComm = getTargetLayer()->getParent()->icCommunicator();
   const int rcvProc = 0;
   if( icComm->commRank() != rcvProc ) {
      return 0;
   }
   for(int b = 0; b < parent->getNBatch(); b++){
      if(timed>2.0f){
         assert((fMin[b]>-0.001)&&(fMin[b]<0.001));
         assert((fMax[b]>-0.001)&&(fMax[b]<0.001));
         assert((avg[b]>-0.001)&&(avg[b]<0.001));
      }
   }

   return status;
}
int CloneKernelConnTestProbe::outputState(double timed)
{
   int status = StatsProbe::outputState(timed);
   InterColComm * icComm = getTargetLayer()->getParent()->icCommunicator();
   const int rcvProc = 0;
   if( icComm->commRank() != rcvProc ) {
      return 0;
   }

   for(int b = 0; b < getParent()->getNBatch(); b++){
      if(timed>2.0f){
         assert(fabs(fMin[b]) < 1e-6);
         assert(fabs(fMax[b]) < 1e-6);
         assert(fabs(avg[b]) < 1e-6);
      }
   }

   return status;
}
Beispiel #18
0
/**
 * @time
 * @l
 */
int MPITestProbe::outputState(double timed) {
	int status = StatsProbe::outputState(timed);
	InterColComm * icComm = getTargetLayer()->getParent()->icCommunicator();
	const int rcvProc = 0;
	if( icComm->commRank() != rcvProc ) {
		return status;
	}
	double tol = 1e-4f;

	// if many to one connection, each neuron should receive its global x/y/f position
	// if one to many connection, the position of the nearest sending cell is received
	// assume sending layer has scale factor == 1
	int xScaleLog2 = getTargetLayer()->getCLayer()->xScale;

	// determine min/max position of receiving layer
	const PVLayerLoc * loc = getTargetLayer()->getLayerLoc();
	int nf = loc->nf;
	int nxGlobal = loc->nxGlobal;
	int nyGlobal = loc->nyGlobal;
	float min_global_xpos = xPosGlobal(0, xScaleLog2, nxGlobal, nyGlobal, nf);
	int kGlobal = nf * nxGlobal * nyGlobal - 1;
	float max_global_xpos = xPosGlobal(kGlobal, xScaleLog2, nxGlobal, nyGlobal, nf);

	if (xScaleLog2 < 0) {
		float xpos_shift = 0.5 - min_global_xpos;
		min_global_xpos = 0.5;
		max_global_xpos -= xpos_shift;
	}
	float ave_global_xpos = (min_global_xpos + max_global_xpos) / 2.0f;

	outputStream->printf("%s min_global_xpos==%f ave_global_xpos==%f max_global_xpos==%f",
			getMessage(), min_global_xpos, ave_global_xpos, max_global_xpos);
	output() << std::endl;
   for(int b = 0; b < parent->getNBatch(); b++){
      if (timed > 3.0f) {
         assert((fMin[b]/min_global_xpos > (1 - tol)) && (fMin[b]/min_global_xpos < (1 + tol)));
         assert((fMax[b]/max_global_xpos > (1 - tol)) && (fMax[b]/max_global_xpos < (1 + tol)));
         assert((avg[b]/ave_global_xpos > (1 - tol)) && (avg[b]/ave_global_xpos < (1 + tol)));
      }
   }

	return status;
}
Beispiel #19
0
int SegmentLayer::updateState(double timef, double dt) {
   pvdata_t* srcA = originalLayer->getActivity();
   pvdata_t* thisA = getActivity();
   assert(srcA);
   assert(thisA);

   const PVLayerLoc* loc = getLayerLoc();

   //Segment input layer based on segmentMethod
   if(strcmp(segmentMethod, "none") == 0){
      int numBatchExtended = getNumExtendedAllBatches();
      //Copy activity over
      //Since both buffers should be identical size, we can do a memcpy here
      memcpy(thisA, srcA, numBatchExtended * sizeof(pvdata_t));
   }
   else{
      //This case should never happen
      assert(0);
   }

   assert(loc->nf == 1);

   //Clear centerIdxs
   for(int bi = 0; bi < loc->nbatch; bi++){
      centerIdx[bi].clear();
   }

   for(int bi = 0; bi < loc->nbatch; bi++){
      pvdata_t* batchA = thisA + bi * getNumExtended();
      //Reset max/min buffers
      maxX.clear();
      maxY.clear();
      minX.clear();
      minY.clear();

      //Loop through this buffer to fill labelVec and idxVec
      //Looping through restricted, but indices are extended
      for(int yi = loc->halo.up; yi < loc->ny+loc->halo.up; yi++){
         for(int xi = loc->halo.lt; xi < loc->nx+loc->halo.lt; xi++){
            //Convert to local extended linear index
            int niLocalExt = yi * (loc->nx+loc->halo.lt+loc->halo.rt) + xi;
            //Convert yi and xi to global res index
            int globalResYi = yi - loc->halo.up + loc->ky0;
            int globalResXi = xi - loc->halo.lt + loc->kx0;

            //Get label value
            //Note that we're assuming that the activity here are integers,
            //even though the buffer is floats
            int labelVal = round(batchA[niLocalExt]);

            //Calculate max/min x and y for a single batch
            //If labelVal exists in map
            if(maxX.count(labelVal)){
               //Here, we're assuming the 4 maps are in sync, so we use the 
               //.at method, as it will throw an exception as opposed to the 
               //[] operator, which will simply add the key into the map
               if(globalResXi > maxX.at(labelVal)){
                  maxX[labelVal] = globalResXi;
               }
               if(globalResXi < minX.at(labelVal)){
                  minX[labelVal] = globalResXi;
               }
               if(globalResYi > maxY.at(labelVal)){
                  maxY[labelVal] = globalResYi;
               }
               if(globalResYi < minY.at(labelVal)){
                  minY[labelVal] = globalResYi;
               }
            }
            //If doesn't exist, add into map with current vals
            else{
               maxX[labelVal] = globalResXi;
               minX[labelVal] = globalResXi;
               maxY[labelVal] = globalResYi;
               minY[labelVal] = globalResYi;
            }
         }
      }

      //We need to mpi across processors in case a segment crosses an mpi boundary
      InterColComm * icComm = parent->icCommunicator();
      int numMpi = icComm->commSize();
      int rank = icComm->commRank();

      //Local comm rank
      //Non root processes simply send buffer size and then buffers
      int numLabels = maxX.size();

      if(rank != 0){
         //Load buffers
         loadLabelBuf();
         //Send number of labels first
         MPI_Send(&numLabels, 1, MPI_INT, 0, rank, icComm->communicator());
         //Send labels, then max/min buffers
         MPI_Send(labelBuf, numLabels, MPI_INT, 0, rank, icComm->communicator());
         MPI_Send(maxXBuf, numLabels, MPI_INT, 0, rank, icComm->communicator());
         MPI_Send(maxYBuf, numLabels, MPI_INT, 0, rank, icComm->communicator());
         MPI_Send(minXBuf, numLabels, MPI_INT, 0, rank, icComm->communicator());
         MPI_Send(minYBuf, numLabels, MPI_INT, 0, rank, icComm->communicator());

         //Receive the full centerIdxBuf from root process
         int numCenterIdx = 0;
         MPI_Bcast(&numCenterIdx, 1, MPI_INT, 0, icComm->communicator());
         checkIdxBufSize(numCenterIdx);

         MPI_Bcast(allLabelsBuf, numCenterIdx, MPI_INT, 0, icComm->communicator());
         MPI_Bcast(centerIdxBuf, numCenterIdx, MPI_INT, 0, icComm->communicator());

         //Load buffer into centerIdx map
         loadCenterIdxMap(bi, numCenterIdx);
      }
      //Root process stores everything
      else{
         //One recv per buffer
         for(int recvRank = 1; recvRank < numMpi; recvRank++){
            int numRecvLabels = 0;
            MPI_Recv(&numRecvLabels, 1, MPI_INT, recvRank, recvRank, icComm->communicator(), NULL);
            checkLabelBufSize(numRecvLabels);

            MPI_Recv(labelBuf, numRecvLabels, MPI_INT, recvRank, recvRank, icComm->communicator(), NULL);
            MPI_Recv(maxXBuf, numRecvLabels, MPI_INT, recvRank, recvRank, icComm->communicator(), NULL);
            MPI_Recv(maxYBuf, numRecvLabels, MPI_INT, recvRank, recvRank, icComm->communicator(), NULL);
            MPI_Recv(minXBuf, numRecvLabels, MPI_INT, recvRank, recvRank, icComm->communicator(), NULL);
            MPI_Recv(minYBuf, numRecvLabels, MPI_INT, recvRank, recvRank, icComm->communicator(), NULL);

            for(int i = 0; i < numRecvLabels; i++){
               int label = labelBuf[i];
               //Add on to maps
               //If the label already exists, fill with proper max/min
               if(maxX.count(label)){
                  if(maxXBuf[i] > maxX.at(label)){
                     maxX[label] = maxXBuf[i];
                  }
                  if(maxYBuf[i] > maxY.at(label)){
                     maxY[label] = maxYBuf[i];
                  }
                  if(minXBuf[i] < minX.at(label)){
                     minX[label] = minXBuf[i];
                  }
                  if(minYBuf[i] < minY.at(label)){
                     minY[label] = minYBuf[i];
                  }
               }
               else{
                  maxX[label] = maxXBuf[i];
                  maxY[label] = maxYBuf[i];
                  minX[label] = minXBuf[i];
                  minY[label] = minYBuf[i];
               }
            }
         }

         //Maps are now filled with all segments from the image
         //Fill centerIdx based on max/min
         for(std::map<int, int>::iterator it = maxX.begin();
               it != maxX.end(); ++it){
            int label = it->first;
            int centerX = minX.at(label) + (maxX.at(label) - minX.at(label))/2;
            int centerY = minY.at(label) + (maxY.at(label) - minY.at(label))/2;
            //Convert centerpoints (in global res idx) to linear idx (in global res space)
            int centerIdxVal = centerY * (loc->nxGlobal) + centerX;
            //Add to centerIdxMap
            centerIdx[bi][label] = centerIdxVal;
         }

         //Fill centerpoint buffer
         int numCenterIdx = centerIdx[bi].size();
         checkIdxBufSize(numCenterIdx);

         int idx = 0;
         for(std::map<int, int>::iterator it = centerIdx[bi].begin(); 
               it != centerIdx[bi].end(); ++it){
            allLabelsBuf[idx] = it->first;
            centerIdxBuf[idx] = it->second;
            idx++;
         }

         //Broadcast buffers
         MPI_Bcast(&numCenterIdx, 1, MPI_INT, 0, icComm->communicator());
         MPI_Bcast(allLabelsBuf, numCenterIdx, MPI_INT, 0, icComm->communicator());
         MPI_Bcast(centerIdxBuf, numCenterIdx, MPI_INT, 0, icComm->communicator());
      }
   } //End batch loop
   
   //centerIdx now stores each center coordinate of each segment
   return PV_SUCCESS;
}
int RescaleLayerTestProbe::outputState(double timed)
{
   int status = StatsProbe::outputState(timed);
   if (timed==getParent()->getStartTime()) { return PV_SUCCESS; }
   float tolerance = 2.0e-5f;
   InterColComm * icComm = getTargetLayer()->getParent()->icCommunicator();
   bool isRoot = icComm->commRank() == 0;

   RescaleLayer * targetRescaleLayer = dynamic_cast<RescaleLayer *>(getTargetLayer());
   assert(targetRescaleLayer);

   if (targetRescaleLayer->getRescaleMethod()==NULL) {
      fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" does not have rescaleMethod set.  Exiting.\n", name, targetRescaleLayer->getName());
      status = PV_FAILURE;
   }
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "maxmin")) {
      if (!isRoot) { return PV_SUCCESS; }
      for(int b = 0; b < parent->getNBatch(); b++){
         float targetMax = targetRescaleLayer->getTargetMax();
         if (fabs(fMax[b]-targetMax)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has max %f instead of target max %f\n", getName(), targetRescaleLayer->getName(), fMax[b], targetMax);
            status = PV_FAILURE;
         }
         float targetMin = targetRescaleLayer->getTargetMin();
         if (fabs(fMin[b]-targetMin)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has min %f instead of target min %f\n", getName(), targetRescaleLayer->getName(), fMin[b], targetMin);
            status = PV_FAILURE;
         }

         // Now, check whether rescaled activity and original V are colinear.
         PVLayerLoc const * rescaleLoc = targetRescaleLayer->getLayerLoc();
         PVHalo const * rescaleHalo = &rescaleLoc->halo;
         int nk = rescaleLoc->nx * rescaleLoc->nf;
         int ny = rescaleLoc->ny;
         int rescaleStrideYExtended = (rescaleLoc->nx + rescaleHalo->lt + rescaleHalo->rt) * rescaleLoc->nf;
         int rescaleExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b * targetRescaleLayer->getNumExtended() + rescaleExtendedOffset;
         PVLayerLoc const * origLoc = targetRescaleLayer->getOriginalLayer()->getLayerLoc();
         PVHalo const * origHalo = &origLoc->halo;
         assert(nk == origLoc->nx * origLoc->nf);
         assert(ny == origLoc->ny);
         int origStrideYExtended = (origLoc->nx + origHalo->lt + origHalo->rt) * origLoc->nf;
         int origExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * origData = targetRescaleLayer->getOriginalLayer()->getLayerData() + b * targetRescaleLayer->getOriginalLayer()->getNumExtended() + origExtendedOffset;

         bool iscolinear = colinear(nk, ny, origStrideYExtended, rescaleStrideYExtended, origData, rescaledData, tolerance, NULL, NULL, NULL);
         if (!iscolinear) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": Rescale layer \"%s\" data is not a linear rescaling of original membrane potential.\n", getName(), targetRescaleLayer->getName());
            status = PV_FAILURE;
         }
      }
   }
   //l2 norm with a patch size of 1 (default) should be the same as rescaling with meanstd with target mean 0 and std of 1/sqrt(patchsize)
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "meanstd") || !strcmp(targetRescaleLayer->getRescaleMethod(), "l2")) {
      if (!isRoot) { return PV_SUCCESS; }
      for(int b = 0; b < parent->getNBatch(); b++){
         float targetMean, targetStd;
         if(!strcmp(targetRescaleLayer->getRescaleMethod(), "meanstd")){
            targetMean = targetRescaleLayer->getTargetMean();
            targetStd = targetRescaleLayer->getTargetStd();
         }
         else{
            targetMean = 0;
            targetStd = 1/sqrt((float)targetRescaleLayer->getL2PatchSize());
         }

         if (fabs(avg[b]-targetMean)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has mean %f instead of target mean %f\n", getName(), targetRescaleLayer->getName(), (double)avg[b], targetMean);
            status = PV_FAILURE;
         }
         if (sigma[b]>tolerance && fabs(sigma[b]-targetStd)>tolerance) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\" has std.dev. %f instead of target std.dev. %f\n", getName(), targetRescaleLayer->getName(), (double)sigma[b], targetStd);
            status = PV_FAILURE;
         }

         // Now, check whether rescaled activity and original V are colinear.
         PVLayerLoc const * rescaleLoc = targetRescaleLayer->getLayerLoc();
         PVHalo const * rescaleHalo = &rescaleLoc->halo;
         int nk = rescaleLoc->nx * rescaleLoc->nf;
         int ny = rescaleLoc->ny;
         int rescaleStrideYExtended = (rescaleLoc->nx + rescaleHalo->lt + rescaleHalo->rt) * rescaleLoc->nf;
         int rescaleExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b*targetRescaleLayer->getNumExtended() + rescaleExtendedOffset;
         PVLayerLoc const * origLoc = targetRescaleLayer->getOriginalLayer()->getLayerLoc();
         PVHalo const * origHalo = &origLoc->halo;
         assert(nk == origLoc->nx * origLoc->nf);
         assert(ny == origLoc->ny);
         int origStrideYExtended = (origLoc->nx + origHalo->lt + origHalo->rt) * origLoc->nf;
         int origExtendedOffset = kIndexExtended(0, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
         pvadata_t const * origData = targetRescaleLayer->getOriginalLayer()->getLayerData() + b*targetRescaleLayer->getOriginalLayer()->getNumExtended() + origExtendedOffset;

         bool iscolinear = colinear(nk, ny, origStrideYExtended, rescaleStrideYExtended, origData, rescaledData, tolerance, NULL, NULL, NULL);
         if (!iscolinear) {
            fprintf(stderr, "RescaleLayerTestProbe \"%s\": Rescale layer \"%s\" data is not a linear rescaling of original membrane potential.\n", getName(), targetRescaleLayer->getName());
            status = PV_FAILURE;
         }
      }
   }
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "pointmeanstd")) {
      PVLayerLoc const * loc = targetRescaleLayer->getLayerLoc();
      int nf = loc->nf;
      if (nf<2) { return PV_SUCCESS; }
      PVHalo const * halo = &loc->halo;
      float targetMean = targetRescaleLayer->getTargetMean();
      float targetStd = targetRescaleLayer->getTargetStd();
      int numNeurons = targetRescaleLayer->getNumNeurons();
      for(int b = 0; b < parent->getNBatch(); b++){
         pvpotentialdata_t const * originalData = targetRescaleLayer->getV() + b*targetRescaleLayer->getNumNeurons();
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b*targetRescaleLayer->getNumExtended();
         for (int k=0; k<numNeurons; k+=nf) {
            int kExtended = kIndexExtended(k, loc->nx, loc->ny, loc->nf, halo->lt, halo->rt, halo->dn, halo->up);
            double pointmean = 0.0;
            for (int f=0; f<nf; f++) {
               pointmean += rescaledData[kExtended+f];
            }
            pointmean /= nf;
            double pointstd = 0.0;
            for (int f=0; f<nf; f++) {
               double d = rescaledData[kExtended+f]-pointmean;
               pointstd += d*d;
            }
            pointstd /= nf;
            pointstd = sqrt(pointstd);
            if (fabs(pointmean-targetMean)>tolerance) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", location in rank %d, starting at restricted neuron %d, has mean %f instead of target mean %f\n",
                     getName(), targetRescaleLayer->getName(), getParent()->columnId(), k, pointmean, targetMean);
               status = PV_FAILURE;
            }
            if (pointstd>tolerance && fabs(pointstd-targetStd)>tolerance) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", location in rank %d, starting at restricted neuron %d, has std.dev. %f instead of target std.dev. %f\n",
                     getName(), targetRescaleLayer->getName(), getParent()->columnId(), k, pointstd, targetStd);
               status = PV_FAILURE;
            }
            bool iscolinear = colinear(nf, 1, 0, 0, &originalData[k], &rescaledData[kExtended], tolerance, NULL, NULL, NULL);
            if (!iscolinear) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", location in rank %d, starting at restricted neuron %d, is not a linear rescaling.\n",
                     getName(), targetRescaleLayer->getName(), parent->columnId(), k);
               status = PV_FAILURE;
            }
         }
      }
   }
   else if (!strcmp(targetRescaleLayer->getRescaleMethod(), "zerotonegative")) {
      int numNeurons = targetRescaleLayer->getNumNeurons();
      assert(numNeurons == targetRescaleLayer->getOriginalLayer()->getNumNeurons());
      PVLayerLoc const * rescaleLoc = targetRescaleLayer->getLayerLoc();
      PVHalo const * rescaleHalo = &rescaleLoc->halo;
      int nf = rescaleLoc->nf;
      HyPerLayer * originalLayer = targetRescaleLayer->getOriginalLayer();
      PVLayerLoc const * origLoc = originalLayer->getLayerLoc();
      PVHalo const * origHalo = &origLoc->halo;
      assert(origLoc->nf == nf);

      for(int b = 0; b < parent->getNBatch(); b++){
         pvadata_t const * rescaledData = targetRescaleLayer->getLayerData() + b * targetRescaleLayer->getNumExtended();
         pvadata_t const * originalData = originalLayer->getLayerData() + b * originalLayer->getNumExtended();
         for (int k=0; k<numNeurons; k++) {
            int rescale_kExtended = kIndexExtended(k, rescaleLoc->nx, rescaleLoc->ny, rescaleLoc->nf, rescaleHalo->lt, rescaleHalo->rt, rescaleHalo->dn, rescaleHalo->up);
            int orig_kExtended = kIndexExtended(k, origLoc->nx, origLoc->ny, origLoc->nf, origHalo->lt, origHalo->rt, origHalo->dn, origHalo->up);
            pvadata_t observedval = rescaledData[rescale_kExtended];
            pvpotentialdata_t correctval = originalData[orig_kExtended] ? observedval : -1.0;
            if (observedval != correctval) {
               fprintf(stderr, "RescaleLayerTestProbe \"%s\": RescaleLayer \"%s\", rank %d, restricted neuron %d has value %f instead of expected %f\n.",
                     this->getName(), targetRescaleLayer->getName(), parent->columnId(), k, observedval, correctval);
               status = PV_FAILURE;
            }
         }
      }
   }
   else {
      assert(0);  // All allowable rescaleMethod values are handled above.
   }
   if (status == PV_FAILURE) {
      exit(EXIT_FAILURE);
   }
   return status;
}
int MapReduceKernelConn::reduceKernels(const int arborID) {
	int status = HyPerConn::reduceKernels(arborID);
	int rootproc = 0;
	InterColComm *icComm = parent->icCommunicator();
	const int numPatches = getNumDataPatches();
	const size_t patchSize = nxp * nyp * nfp * sizeof(pvdata_t);
	const size_t localSize = numPatches * patchSize;
	const size_t arborSize = localSize * this->numberOfAxonalArborLists();
	if (icComm->commRank() == rootproc) {
		// write dW for this instantiation of PetaVision to disk
		status = HyPerConn::writeWeights(NULL, this->get_dwDataStart(),
				getNumDataPatches(), dWeightsList[dWeightFileIndex],
				parent->simulationTime(), /*writeCompressedWeights*/false, /*last*/
				false);
		if (status != PV_SUCCESS) {
			fprintf(stderr,
					"MapReduceKernelConn::reduceKernels::HyPerConn::writeWeights: problem writing to file %s, "
							"SHUTTING DOWN\n", dWeightsList[dWeightFileIndex]);
			exit(EXIT_FAILURE);
		} // status
		  // use dWeightsList to read in the weights written by other PetaVision instantiations
		double dW_time;
		double simulation_time = parent->simulationTime();
		int filetype, datatype;
		int numParams = NUM_BIN_PARAMS + NUM_WGT_EXTRA_PARAMS;
		int params[NUM_BIN_PARAMS + NUM_WGT_EXTRA_PARAMS];
		const PVLayerLoc *preLoc = this->preSynapticLayer()->getLayerLoc();
		int file_count = 0;
		for (file_count = 0; file_count < num_dWeightFiles; file_count++) {
			if (file_count == dWeightFileIndex) {
				continue;
			}
			int num_attempts = 0;
			const int MAX_ATTEMPTS = 5;
			dW_time = 0;
			while (dW_time < simulation_time && num_attempts <= MAX_ATTEMPTS) {
				pvp_read_header(dWeightsList[file_count], icComm, &dW_time,
						&filetype, &datatype, params, &numParams);
				num_attempts++;
			} // while
			if (num_attempts > MAX_ATTEMPTS) {
				fprintf(stderr,
						"PV::MapReduceKernelConn::reduceKernels: problem reading arbor file %s, SHUTTING DOWN\n",
						dWeightsList[file_count]);
				status = EXIT_FAILURE;
				exit(EXIT_FAILURE);
			} // num_attempts > MAX_ATTEMPTS
			int status = PV::readWeights(NULL, get_dwDataStart(),
					this->numberOfAxonalArborLists(), this->getNumDataPatches(), nxp, nyp, nfp,
					dWeightsList[file_count], icComm, &dW_time, preLoc);
			if (status != PV_SUCCESS) {
				fprintf(stderr,
						"MapReduceKernelConn::reduceKernels::PV::readWeights: problem reading file %s, "
								"SHUTTING DOWN\n", dWeightsList[file_count]);
				exit(EXIT_FAILURE);
			} // status
		} // file_count < numWeightFiles
		  // average dW from map-reduce
		pvwdata_t * dW_data = this->get_dwDataStart(0);
		for (int i_dW = 0; i_dW < arborSize; i_dW++) {
			dW_data[i_dW] /= num_dWeightFiles;
		}
	} // rootproc

	// broadcast map-reduced dWeights to all non-root processes
	MPI_Comm mpi_comm = icComm->communicator();
#ifdef PV_USE_MPI
	MPI_Bcast(this->get_wDataStart(0), arborSize, MPI_FLOAT, rootproc, mpi_comm);
#endif
	return PV_BREAK;
}