Esempio n. 1
0
int MomentumConn::updateWeights(int arborId){
   if(timeBatchIdx != timeBatchPeriod - 1){
      return PV_SUCCESS;
   }
   //Add momentum right before updateWeights
   for(int kArbor = 0; kArbor < this->numberOfAxonalArborLists(); kArbor++){
      applyMomentum(arborId);
   }

   //Saved to prevweights
   assert(prev_dwDataStart);
   std::memcpy(*prev_dwDataStart, *get_dwDataStart(),
         sizeof(pvwdata_t) *
         numberOfAxonalArborLists() * 
         nxp * nyp * nfp *
         getNumDataPatches());


   // add dw to w
   for(int kArbor = 0; kArbor < this->numberOfAxonalArborLists(); kArbor++){
      pvwdata_t * w_data_start = get_wDataStart(kArbor);
      for( long int k=0; k<patchStartIndex(getNumDataPatches()); k++ ) {
         w_data_start[k] += get_dwDataStart(kArbor)[k];
      }
   }
   return PV_BREAK;
}
Esempio n. 2
0
int MomentumConn::allocateDataStructures(){
   HyPerConn::allocateDataStructures();
   if (!plasticityFlag) return PV_SUCCESS;
   int sx = nfp;
   int sy = sx * nxp;
   int sp = sy * nyp;
   int nPatches = getNumDataPatches();

   const int numAxons = numberOfAxonalArborLists();

   //Allocate dw buffer for previous dw
   prev_dwDataStart = (pvwdata_t **) calloc(numAxons, sizeof(pvwdata_t *));
   if( prev_dwDataStart == NULL ) {
      createArborsOutOfMemory();
      assert(false);
   }
   prev_dwDataStart[0] = (pvwdata_t*) calloc(numAxons * nxp * nyp * nfp * nPatches, sizeof(pvwdata_t));
   assert(prev_dwDataStart[0] != NULL);
   for (int arborId = 0; arborId < numAxons; arborId++) {
      prev_dwDataStart[arborId] = (prev_dwDataStart[0] + sp * nPatches * arborId);
      assert(prev_dwDataStart[arborId] != NULL);
   } // loop over arbors

   assert(clones.size() == 0);

   return PV_SUCCESS;
}
Esempio n. 3
0
int PoolingConn::constructWeights() {
    int sx = nfp;
    int sy = sx * nxp;
    int sp = sy * nyp;
    int nPatches = getNumDataPatches();
    int status = PV_SUCCESS;

    assert(!parent->parameters()->presentAndNotBeenRead(name, "shrinkPatches"));
    // createArbors() uses the value of shrinkPatches.  It should have already been read in ioParamsFillGroup.
    //allocate the arbor arrays:
    createArbors();

    setPatchStrides();

    for (int arborId=0; arborId<numAxonalArborLists; arborId++) {
        PVPatch *** wPatches = get_wPatches();
        status = createWeights(wPatches, arborId);
        assert(wPatches[arborId] != NULL);
        if (shrinkPatches_flag || arborId == 0) {
            status |= adjustAxonalArbors(arborId);
        }
    }  // arborId

    //call to initializeWeights moved to BaseConnection::initializeState()
    status |= initPlasticityPatches();
    assert(status == 0);
    if (shrinkPatches_flag) {
        for (int arborId=0; arborId<numAxonalArborLists; arborId++) {
            shrinkPatches(arborId);
        }
    }

    return status;

}
Esempio n. 4
0
int MomentumConn::checkpointRead(const char * cpDir, double * timeptr) {
   HyPerConn::checkpointRead(cpDir, timeptr);
   if (!plasticityFlag) return PV_SUCCESS;
   clearWeights(prev_dwDataStart, getNumDataPatches(), nxp, nyp, nfp);
   char * path = parent->pathInCheckpoint(cpDir, getName(), "_prev_dW.pvp");
   PVPatch *** patches_arg = sharedWeights ? NULL : get_wPatches();
   double filetime=0.0;
   int status = PV::readWeights(patches_arg, prev_dwDataStart, numberOfAxonalArborLists(), getNumDataPatches(), nxp, nyp, nfp, path, parent->icCommunicator(), &filetime, pre->getLayerLoc());
   if (parent->columnId()==0 && timeptr && *timeptr != filetime) {
      fprintf(stderr, "Warning: \"%s\" checkpoint has timestamp %g instead of the expected value %g.\n", path, filetime, *timeptr);
   }
   free(path);
   return status;
}
Esempio n. 5
0
int GradientCheckConn::allocateDataStructures() {
   int status = PV::HyPerConn::allocateDataStructures();

   //Check num weights against num timesteps
   int numDataPatches = getNumDataPatches();
   int numWeights = nxp * nyp * nfp;
   int numArbors = numAxonalArborLists;
 
   if(parent->getFinalStep() - parent->getInitialStep() > numDataPatches * numWeights * numArbors + 2){
      std::cout << "Maximum number of steps for GradientCheckConn is " << numDataPatches * numWeights * numArbors + 2 << "\n";
      exit(-1);
   }
   return status;
}
Esempio n. 6
0
//TODO checkpointing not working with batching, must write checkpoint exactly at period
int MomentumConn::checkpointWrite(const char * cpDir) {
   HyPerConn::checkpointWrite(cpDir);
   if (!plasticityFlag) return PV_SUCCESS;
   char filename[PV_PATH_MAX];
   int chars_needed = snprintf(filename, PV_PATH_MAX, "%s/%s_prev_dW.pvp", cpDir, name);
   if(chars_needed >= PV_PATH_MAX) {
      if ( parent->icCommunicator()->commRank()==0 ) {
         fprintf(stderr, "HyPerConn::checkpointFilename error: path \"%s/%s_W.pvp\" is too long.\n", cpDir, name);
      }
      abort();
   }
   PVPatch *** patches_arg = sharedWeights ? NULL : get_wPatches();
   int status = writeWeights(patches_arg, prev_dwDataStart, getNumDataPatches(), filename, parent->simulationTime(), writeCompressedCheckpoints, /*last*/true);
   assert(status==PV_SUCCESS);
   return PV_SUCCESS;
}
Esempio n. 7
0
int VaryingHyPerConn::updateWeights(int axonId) {
   int syPatch = yPatchStride();
   for( int kPatch = 0; kPatch < getNumDataPatches(); kPatch++) {
      PVPatch * W = getWeights(kPatch, axonId);
      int nkPatch = fPatchSize() * W->nx;
      pvwdata_t * Wdata = get_wData(axonId, kPatch); // W->data;
      pvdata_t * dWdata = get_dwData(axonId, kPatch);
      for(int kyPatch = 0; kyPatch < W->ny; kyPatch++) {
         for(int kPatch = 0; kPatch < nkPatch; kPatch++) {
            Wdata[kPatch] += dWdata[kPatch];
         }
         dWdata += syPatch;
      }
   }
   return PV_SUCCESS;
}
int LCALIFLateralKernelConn::checkpointWrite(const char * cpDir) {
   int status = HyPerConn::checkpointWrite(cpDir);
   char filename[PV_PATH_MAX];
   int chars_needed = snprintf(filename, PV_PATH_MAX, "%s/%s_integratedSpikeCount.pvp", cpDir, name);
   if (chars_needed >= PV_PATH_MAX) {
      fprintf(stderr, "LCALIFLateralKernelConn::checkpointWrite error.  Path \"%s/%s_integratedSpikeCount.pvp\" is too long.\n", cpDir, name);
      abort();
   }
   int status2 = HyPerLayer::writeBufferFile(filename, parent->icCommunicator(), parent->simulationTime(), &integratedSpikeCount, 1/*numbands*/, false/*extended*/, pre->getLayerLoc());
   if (status2!=PV_SUCCESS) status = status2;

   chars_needed = snprintf(filename, PV_PATH_MAX, "%s/%s_dW.pvp", cpDir, name);
   assert(chars_needed < PV_PATH_MAX);
   status2 = HyPerConn::writeWeights(NULL, get_dwDataStart(), getNumDataPatches(), filename, parent->simulationTime(), writeCompressedCheckpoints, true);
   if (status2!=PV_SUCCESS) status = status2;
   return status;
}
Esempio n. 9
0
  int LCAConn::update_dW(int axonId)
  { // compute dW but don't add them to the weights yet.
    // That takes place in reduceKernels, so that the output is
    // independent of the number of processors.
    int nExt = preSynapticLayer()->getNumExtended();
    int numKernelIndices = getNumDataPatches();
    const pvdata_t * preactbuf = preSynapticLayer()->getLayerData(getDelay(axonId));
    const pvdata_t * postactbuf = postSynapticLayer()->getLayerData(getDelay(axonId));

    int sya = (post->getLayerLoc()->nf * (post->getLayerLoc()->nx + 2*post->getLayerLoc()->nb));
    
    for(int kExt=0; kExt<nExt;kExt++) {
      PVPatch * weights = getWeights(kExt,axonId);
      size_t offset = getAPostOffset(kExt, axonId);
      pvdata_t preact = preactbuf[kExt];
      int ny = weights->ny;
      int nk = weights->nx * nfp;
      const pvdata_t * postactRef = &postactbuf[offset];
      pvdata_t * dwdata = get_dwData(axonId, kExt);
      int lineoffsetw = 0;
      int lineoffseta = 0;
      for( int y=0; y<ny; y++ ) {
	for( int k=0; k<nk; k++ ) {
	  dwdata[lineoffsetw + k] += updateRule_dW(preact, postactRef[lineoffseta+k],lineoffseta+k);
	}
	lineoffsetw += syp;
	lineoffseta += sya;
      }
    }
    
    // Divide by (numNeurons/numKernels)
    int divisor = pre->getNumNeurons()/numKernelIndices;
    assert( divisor*numKernelIndices == pre->getNumNeurons() );
    for( int kernelindex=0; kernelindex<numKernelIndices; kernelindex++ ) {
      int numpatchitems = nxp*nyp*nfp;
      pvdata_t * dwpatchdata = get_dwDataHead(axonId,kernelindex);
      for( int n=0; n<numpatchitems; n++ ) {
	dwpatchdata[n] /= divisor;
      }
    }

    lastUpdateTime = parent->simulationTime();

    return PV_SUCCESS;    
  }
Esempio n. 10
0
int VaryingHyPerConn::allocateDataStructures() {
   HyPerConn::allocateDataStructures();
   // initialize all dW's to one.
   int syPatch = yPatchStride();
   for(int kAxon = 0; kAxon < numberOfAxonalArborLists(); kAxon++){
      for(int kPatch = 0; kPatch < getNumDataPatches(); kPatch++){
         PVPatch * W = getWeights(kPatch, kAxon);
         int nkPatch = fPatchSize() * W->nx;
         float * dWdata = get_dwData(kAxon, kPatch);
         for(int kyPatch = 0; kyPatch < W->ny; kyPatch++){
            for(int kPatch = 0; kPatch < nkPatch; kPatch++){
               dWdata[kPatch] = 1.0f;
            }
            dWdata += syPatch;
         }
      }
   }

   return PV_SUCCESS;
}
int LCALIFLateralKernelConn::updateWeights(int axonId) {
   if (plasticityFlag) {
      float normalizer = parent->getDeltaTime()/getInhibitionTimeConstant();
      for (int kernel=0; kernel<getNumDataPatches(); kernel++) {
         pvwdata_t * dw_data = get_dwDataHead(axonId,kernel);
         pvwdata_t * w_data = get_wDataHead(axonId,kernel);
         for (int y=0; y<nyp; y++) {
            for (int x=0; x<nxp; x++) {
               for (int f=0; f<nfp; f++) {
                  int idx = sxp*x + syp*y + sfp*f;
                  pvdata_t dw = dw_data[idx] * normalizer;
                  pvwdata_t w = w_data[idx] + (weightUpdatePeriod/parent->getDeltaTime())*dw;
                  if (w<0) w=0;
                  w_data[idx] = w;
               }
            }
         }
      }
   }
   return PV_SUCCESS;
}
Esempio n. 12
0
int MomentumConn::applyMomentum(int arbor_ID){
   int nExt = preSynapticLayer()->getNumExtended();
   const PVLayerLoc * loc = preSynapticLayer()->getLayerLoc();
   if(sharedWeights){
      int numKernels = getNumDataPatches();
      //Shared weights done in parallel, parallel in numkernels
#ifdef PV_USE_OPENMP_THREADS
#pragma omp parallel for
#endif
      for(int kernelIdx = 0; kernelIdx < numKernels; kernelIdx++){
         pvwdata_t * dwdata_start  = get_dwDataHead(arbor_ID, kernelIdx);
         pvwdata_t * prev_dw_start = get_prev_dwDataHead(arbor_ID, kernelIdx);
         pvwdata_t * wdata_start   = get_wDataHead(arbor_ID, kernelIdx);
         if(!strcmp(momentumMethod, "simple")){
            for(int k = 0; k < nxp*nyp*nfp; k++){
               dwdata_start[k] += momentumTau * prev_dw_start[k] - momentumDecay*wdata_start[k];
            }
         }
         else if(!strcmp(momentumMethod, "viscosity")){
            for(int k = 0; k < nxp*nyp*nfp; k++){
               //dwdata_start[k] = momentumTau * (prev_dw_start[k] + dwdata_start[k]) * (1 - exp(-1.0/ momentumTau)) - momentumDecay*wdata_start[k];
               dwdata_start[k] = (prev_dw_start[k] * exp(-1.0/ momentumTau)) + dwdata_start[k] - momentumDecay*wdata_start[k];
            }
         }
         else if(!strcmp(momentumMethod, "alex")){
            for(int k = 0; k < nxp*nyp*nfp; k++){
               //weight_inc[i] := momW * weight_inc[i-1] - wc * epsW * weights[i-1] + epsW * weight_grads[i]
               //   weights[i] := weights[i-1] + weight_inc[i]
               dwdata_start[k] = momentumTau * prev_dw_start[k] - momentumDecay * getDWMax()* wdata_start[k] + dwdata_start[k];
            }
         }
      }
   }
   else{
      std::cout << "Warning: Momentum not implemented for non-shared weights, not implementing momentum\n";
   }
   return PV_SUCCESS;
}
Esempio n. 13
0
int MomentumConn::allocateDataStructures(){
   int status = HyPerConn::allocateDataStructures();
   if (status==PV_POSTPONE) { return status; }
   if (!plasticityFlag) return status;
   int sx = nfp;
   int sy = sx * nxp;
   int sp = sy * nyp;
   int nPatches = getNumDataPatches();

   const int numAxons = numberOfAxonalArborLists();

   //Allocate dw buffer for previous dw
   prev_dwDataStart = (pvwdata_t **) pvCalloc(numAxons, sizeof(pvwdata_t *));
   prev_dwDataStart[0] = (pvwdata_t*) pvCalloc(numAxons * nxp * nyp * nfp * nPatches, sizeof(pvwdata_t));
   for (int arborId = 0; arborId < numAxons; arborId++) {
      prev_dwDataStart[arborId] = (prev_dwDataStart[0] + sp * nPatches * arborId);
      assert(prev_dwDataStart[arborId] != NULL);
   } // loop over arbors

   //assert(clones.size() == 0);

   return PV_SUCCESS;
}
Esempio n. 14
0
int CopyConn::copy(int arborId) {
   size_t arborsize = (size_t) (xPatchSize() * yPatchSize() * fPatchSize() * getNumDataPatches()) * sizeof(pvwdata_t);
   memcpy(get_wDataStart(arborId), originalConn->get_wDataStart(arborId), arborsize);
   return PV_SUCCESS;
}
Esempio n. 15
0
//Connections update first
int GradientCheckConn::updateState(double time, double dt){
   int status = PV_SUCCESS;
   int weightIdx = parent->getCurrentStep() - parent->getInitialStep() - 2;
   std::cout << "weightIdx " << weightIdx << "\n";
   int numPatch = nxp * nyp * nfp;
   int numData = getNumDataPatches();
   int arborIdx = weightIdx / (numPatch * numData);
   int dataIdx = (weightIdx / numPatch) % numData;
   int patchIdx = weightIdx % numPatch;

   if(firstRun){
      initialize_dW(0);
      firstRun = false;
      return PV_SUCCESS;
   }
   
   //Grab cost from previous timestep
   if(secondRun){
      //First run does regular updateState to calculate dw buffer
      for(int arborId=0;arborId<numberOfAxonalArborLists();arborId++) {
         status = calc_dW();        // Calculate changes in weights
         if (status==PV_BREAK) { break; }
         assert(status == PV_SUCCESS);
      }
      //for (int arborID = 0; arborID < numberOfAxonalArborLists(); arborID++) {
      //   if(sharedWeights){
      //      status = reduceKernels(arborID); // combine partial changes in each column
      //      if (status == PV_BREAK) {
      //         break;
      //      }
      //      assert(status == PV_SUCCESS);
      //   }
      //}
      //No update weights
      origCost = getCost();
      secondRun = false;
   }

   //Does not update after first run
   //Check if we are in bounds for non-shared weights
   if(!sharedWeights){
      PVPatch* weights = getWeights(dataIdx, arborIdx);
      //Calculate x and y of patchIdx and compare it to offset
      int xPatchIdx = kxPos(patchIdx, nxp, nyp, nfp);
      int yPatchIdx = kyPos(patchIdx, nxp, nyp, nfp);
      int xOffsetIdx = kxPos(weights->offset, nxp, nyp, nfp);
      int yOffsetIdx = kyPos(weights->offset, nxp, nyp, nfp);

      //If index is oob, skip
      if(xPatchIdx < xOffsetIdx || xPatchIdx >= xOffsetIdx + weights->nx ||
         yPatchIdx < yOffsetIdx || yPatchIdx >= yOffsetIdx + weights->ny){
         return PV_SUCCESS;
      }
   }

   //Calculate difference in numerical method and backprop method
   if(prevIdx != -1){
      currCost = getCost();
      //Check for accuracy
      float numGradient = (currCost - origCost)/epsilon;
      float backpropGradient = get_dwDataStart()[0][prevIdx] / dWMax;
      std::cout << "Numerical gradient: " << numGradient << "  Backprop gradient: " << backpropGradient << "\n";

      //if(fabs(numGradient + backpropGradient) >= .1){
      //   std::cout << "Numerical gradient: " << numGradient << "  Backprop gradient: " << backpropGradient << "\n";
      //   exit(-1);

      //}
   }

   //Restore weight
   if(prevIdx != -1){
      std::cout << "Restoring weight " << prevIdx << " to " << prevWeightVal << "\n";
      get_wDataStart()[0][prevIdx] = prevWeightVal;
   }

   //Set next weight if not the end
   if(weightIdx < numberOfAxonalArborLists() * numData * numPatch){
      prevWeightVal = get_wDataStart()[0][weightIdx];
      prevIdx = weightIdx;
      get_wDataStart()[0][weightIdx] += epsilon;
      std::cout << "Setting weight " << weightIdx << " to " << prevWeightVal + epsilon << "\n";
   }
   else{
      std::cout << "END\n";
   }

   return status;
}
int LCALIFLateralKernelConn::allocateDataStructures() {
   int status = HyPerConn::allocateDataStructures();

   // Neurons don't inhibit themselves, only their neighbors; set self-interaction weights to mmzero.
   assert(nxp % 2 == 1 && nyp % 2 == 1 && getNumDataPatches()==nfp);
   for (int k=0; k<getNumDataPatches(); k++) {
      int n = kIndex((nxp-1)/2, (nyp-1)/2, k, nxp, nyp, nfp);
      get_wDataHead(0, k)[n] = 0.0f;
   }

   integratedSpikeCountCube = pvcube_new(pre->getLayerLoc(), pre->getNumExtended());
   integratedSpikeCount = integratedSpikeCountCube->data;
   for (int k=0; k<pre->getNumExtended(); k++) {
      integratedSpikeCount[k] = integrationTimeConstant*getTargetRateKHz(); // Spike counts initialized to equilibrium value
   }
   mpi_datatype = Communicator::newDatatypes(pre->getLayerLoc());
   if (mpi_datatype==NULL) {
      fprintf(stderr, "LCALIFLateralKernelConn \"%s\" error creating mpi_datatype\n", name);
      abort();
   }

   // Compute the number of times each patch contributes to dw, for proper averaging.
   int num_arbors = numberOfAxonalArborLists();
   interiorCounts = (float **) calloc(num_arbors, sizeof(float *));
   if (interiorCounts==NULL) {
      fprintf(stderr, "LCALIFLateralKernelConn::initialize \"%s\" error: unable to allocate memory for interiorCounts pointer\n", name);
   }
   interiorCounts[0] = (float *) calloc(getNumDataPatches()*nxp*nyp*nfp, sizeof(float));
   if (interiorCounts[0]==NULL) {
      fprintf(stderr, "LCALIFLateralKernelConn::initialize \"%s\" error: unable to allocate memory for interiorCounts\n", name);
   }
   for (int arbor=1; arbor<num_arbors; arbor++) {
      interiorCounts[arbor] = interiorCounts[0]+arbor*getNumDataPatches()*nxp*nyp*nfp;
   }

   const PVLayerLoc * preloc = pre->getLayerLoc();
   int nxpre = preloc->nx;
   int nypre = preloc->ny;
   int nfpre = preloc->nf;

   int nExt = pre->getNumExtended();
   int sya = getPostExtStrides()->sy;
   int nxglob = preloc->nxGlobal;
   int nyglob = preloc->nyGlobal;
   int kx0 = preloc->kx0;
   int ky0 = preloc->ky0;
   for (int arbor=0; arbor<numberOfAxonalArborLists(); arbor++) {
      for(int kExt=0; kExt<nExt;kExt++) {
         int xglob = kxPos(kExt, nxpre + preloc->halo.lt + preloc->halo.rt, nypre + preloc->halo.dn + preloc->halo.up, nfpre) + kx0 - preloc->halo.lt;
         int yglob = kyPos(kExt, nypre + preloc->halo.lt + preloc->halo.rt, nypre + preloc->halo.dn + preloc->halo.up, nfpre) + ky0 - preloc->halo.up;
         if (xglob < 0 || xglob >= nxglob || yglob < 0 || yglob >= nyglob) {
            continue;
         }
         PVPatch * weights = getWeights(kExt,arbor);
         int offset = (int) getAPostOffset(kExt, arbor);
         int ny = weights->ny;
         int nk = weights->nx * nfp;
         int interiorCountOffset = get_wData(arbor, kExt)-get_wDataStart(arbor);
         int lineoffsetw = 0;
         int lineoffseta = 0;
         for( int y=0; y<ny; y++ ) {
            for( int k=0; k<nk; k++ ) {
               int postactindex = offset+lineoffseta+k;
               if (postactindex != kExt) { // Neurons don't inhibit themselves
                  interiorCounts[arbor][interiorCountOffset + lineoffsetw + k]++;
               }
            }
            lineoffsetw += syp;
            lineoffseta += sya;
         }
      }
   }
   int bufsize = numberOfAxonalArborLists() * getNumDataPatches() * nxp * nyp * nfp;
// TODO-CER-2014.3.26 - Ensure that reduction is done when not using MPI
#ifdef PV_USE_MPI
   MPI_Allreduce(MPI_IN_PLACE, interiorCounts[0], bufsize, MPI_FLOAT, MPI_SUM, parent->icCommunicator()->communicator());
#endif

   return status;
}
int LCALIFLateralKernelConn::update_dW(int axonId) {
   if (parent->simulationTime() < dWUpdateTime) {
      return PV_SUCCESS;
   }
   dWUpdateTime += dWUpdatePeriod;
   int nExt = preSynapticLayer()->getNumExtended();
   int numKernelIndices = getNumDataPatches();
   updateIntegratedSpikeCount();
   float target_rate_sq = getTargetRateKHz()*getTargetRateKHz();
   const pvdata_t * preactbuf = integratedSpikeCount;
   const pvdata_t * postactbuf = integratedSpikeCount;

   int sya = (post->getLayerLoc()->nf * (post->getLayerLoc()->nx + post->getLayerLoc()->halo.lt + post->getLayerLoc()->halo.rt));

   const PVLayerLoc * preloc = pre->getLayerLoc();
   int nxpre = preloc->nx;
   int nypre = preloc->ny;
   int nfpre = preloc->nf;
   int nxglob = preloc->nxGlobal;
   int nyglob = preloc->nyGlobal;
   int kx0 = preloc->kx0;
   int ky0 = preloc->ky0;
   for(int kExt=0; kExt<nExt;kExt++) {
      int xglob = kxPos(kExt, nxpre + preloc->halo.lt + preloc->halo.rt, nypre + preloc->halo.dn + preloc->halo.up, nfpre) + kx0 - preloc->halo.lt;
      int yglob = kyPos(kExt, nxpre + preloc->halo.lt + preloc->halo.rt, nypre + preloc->halo.dn + preloc->halo.up, nfpre) + ky0 - preloc->halo.dn;
      if (xglob < 0 || xglob >= nxglob || yglob < 0 || yglob >= nyglob) {
         continue;
      }
      PVPatch * weights = getWeights(kExt,axonId);
      size_t offset = getAPostOffset(kExt, axonId);
      pvdata_t preactrate = preactbuf[kExt]/integrationTimeConstant;
      int ny = weights->ny;
      int nk = weights->nx * nfp;
      pvwdata_t * dwdata = get_dwData(axonId, kExt);
      int lineoffsetw = 0;
      int lineoffseta = 0;
      for( int y=0; y<ny; y++ ) {
         for( int k=0; k<nk; k++ ) {
            int postactindex = offset+lineoffseta+k;
            if (postactindex != kExt) { // Neurons don't inhibit themselves
               pvdata_t postactrate = postactbuf[postactindex]/integrationTimeConstant;
               pvdata_t dw = preactrate*postactrate-target_rate_sq;
               dwdata[lineoffsetw + k] += dw;
            }
         }
         lineoffsetw += syp;
         lineoffseta += sya;
      }
   }
   // Divide each dw by the number of correlations that contributed to that dw (divisorptr was summed over all MPI processes in initialization).
   // Also divide by target_rate_sq to normalize to a dimensionless quantity.
   // The nonlinear filter and the multiplication by dt/tauINH takes place in updateWeights, because the filter has to be applied after reduceKernels
   // and the multiplication by dt/tauINH needs to take place after the filter.
   int patch_size = nxp*nyp*nfp;
   for( int kernelindex=0; kernelindex<numKernelIndices; kernelindex++ ) {
      pvwdata_t * dwpatchdata = get_dwDataHead(axonId,kernelindex);
      float * divisorptr = &interiorCounts[axonId][kernelindex*patch_size];
      for( int n=0; n<patch_size; n++ ) {
         assert(divisorptr[n]>0 || dwpatchdata[n]==0);
         if (divisorptr[n]>0) dwpatchdata[n] /= target_rate_sq * divisorptr[n];
      }
   }

   lastUpdateTime = parent->simulationTime();

   return PV_SUCCESS;
}
Esempio n. 18
0
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;
}