int KernelProbe::patchIndices(HyPerConn * conn) { int nxp = conn->xPatchSize(); int nyp = conn->yPatchSize(); int nfp = conn->fPatchSize(); int nPreExt = conn->getNumWeightPatches(); assert(nPreExt == conn->preSynapticLayer()->getNumExtended()); const PVLayerLoc * loc = conn->preSynapticLayer()->getLayerLoc(); const PVHalo * halo = &loc->halo; int nxPre = loc->nx; int nyPre = loc->ny; int nfPre = loc->nf; int nxPreExt = nxPre+loc->halo.lt+loc->halo.rt; int nyPreExt = nyPre+loc->halo.dn+loc->halo.up; for( int kPre = 0; kPre < nPreExt; kPre++ ) { PVPatch * w = conn->getWeights(kPre,arborID); int xOffset = kxPos(w->offset, nxp, nyp, nfp); int yOffset = kyPos(w->offset, nxp, nyp, nfp); int kxPre = kxPos(kPre,nxPreExt,nyPreExt,nfPre)-loc->halo.lt; int kyPre = kyPos(kPre,nxPreExt,nyPreExt,nfPre)-loc->halo.up; int kfPre = featureIndex(kPre,nxPreExt,nyPreExt,nfPre); fprintf(outputstream->fp," presynaptic neuron %d (x=%d, y=%d, f=%d) uses kernel index %d, starting at x=%d, y=%d\n", kPre, kxPre, kyPre, kfPre, conn->patchIndexToDataIndex(kPre), xOffset, yOffset); } return PV_SUCCESS; }
/** * @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; }
int MaskFromMemoryBuffer::updateState(double time, double dt) { if (imageLayer->getDataLeft() == dataLeft && imageLayer->getDataTop() == dataTop && imageLayer->getDataWidth() == dataRight-dataLeft && imageLayer->getDataHeight() && dataBottom-dataTop) { return PV_SUCCESS; // mask only needs to change if the imageLayer changes its active region } dataLeft = imageLayer->getDataLeft(); dataRight = dataLeft+imageLayer->getDataWidth(); dataTop = imageLayer->getDataTop(); dataBottom = dataTop + imageLayer->getDataHeight(); PVLayerLoc const * loc = getLayerLoc(); for(int b = 0; b < loc->nbatch; b++) { pvdata_t * ABatch = getActivity() + b * getNumExtended(); int const num_neurons = getNumNeurons(); #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for(int ni = 0; ni < num_neurons; ni++) { PVHalo const * halo = &loc->halo; int const nx = loc->nx; int const ny = loc->ny; int const nf = loc->nf; int x = kxPos(ni, nx, ny, nf); int y = kyPos(ni, nx, ny, nf); pvadata_t a = (pvadata_t) (x>=dataLeft && x < dataRight && y >= dataTop && y < dataBottom); int nExt = kIndexExtended(ni, nx, ny, nf, halo->lt, halo->rt, halo->dn, halo->up); ABatch[nExt] = a; } } return PV_SUCCESS; }
// // A replacement for globalIndexFromLocal from conversions.h. // WARNING - any changes in conversions.h should be reflected here. static inline int globalIndexFromLocal_nompi(int kl, PVLayerLoc loc) { int kxg = loc.kx0 + kxPos(kl, loc.nx, loc.ny, loc.nf); int kyg = loc.ky0 + kyPos(kl, loc.nx, loc.ny, loc.nf); int kf = featureIndex(kl, loc.nx, loc.ny, loc.nf); return kIndex(kxg, kyg, kf, loc.nxGlobal, loc.nyGlobal, loc.nf); }
int ImageTestLayer::updateStateWrapper(double time, double dt) { Image::updateStateWrapper(time, dt); const PVLayerLoc * loc = getLayerLoc(); int nx = loc->nx; int ny = loc->ny; int nf = loc->nf; int nbatch = loc->nbatch; for(int b = 0; b < nbatch; b++){ pvdata_t * dataBatch = data + b * getNumExtended(); for(int nkRes = 0; nkRes < getNumNeurons(); nkRes++){ //Calculate extended index int nkExt = kIndexExtended(nkRes, nx, ny, nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up); //checkVal is the value from batch index 0 pvdata_t checkVal = dataBatch[nkExt] * 255; int kxGlobal = kxPos(nkRes, nx, ny, nf) + loc->kx0; int kyGlobal = kyPos(nkRes, nx, ny, nf) + loc->ky0; int kf = featureIndex(nkRes, nx, ny, nf); pvdata_t expectedVal = kIndex(kxGlobal, kyGlobal, kf, loc->nxGlobal, loc->nyGlobal, nf); if(fabs(checkVal - expectedVal) >= 1e-5){ std::cout << "ImageFileIO test Expected: " << expectedVal << " Actual: " << checkVal << "\n"; exit(-1); } } } return PV_SUCCESS; }
/** * @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 CPTestInputLayer::initializeV() { assert(parent->parameters()->value(name, "restart", 0.0f, false)==0.0f); // initializeV should only be called if restart is false const PVLayerLoc * loc = getLayerLoc(); for (int b = 0; b < parent->getNBatch(); b++){ pvdata_t * VBatch = getV() + b * getNumNeurons(); for (int k = 0; k < getNumNeurons(); k++){ int kx = kxPos(k,loc->nx,loc->nx,loc->nf); int ky = kyPos(k,loc->nx,loc->ny,loc->nf); int kf = featureIndex(k,loc->nx,loc->ny,loc->nf); int kGlobal = kIndex(loc->kx0+kx,loc->ky0+ky,kf,loc->nxGlobal,loc->nyGlobal,loc->nf); VBatch[k] = (pvdata_t) kGlobal; } } return PV_SUCCESS; }
int PursuitLayer::updateState(double time, double dt) { if (!updateReady) return PV_SUCCESS; int nx = getLayerLoc()->nx; int ny = getLayerLoc()->ny; int nf = getLayerLoc()->nf; PVHalo const * halo = &getLayerLoc()->halo; pvdata_t * activity = getActivity(); memset(activity, 0, getNumExtended()*sizeof(*activity)); int nxy = nx*ny; for (int kxy=0; kxy<nxy; kxy++) { int kf = foundFeatures[kxy]; if (kf>=0) { int kx = kxPos(kxy,nx,ny,1); int ky = kyPos(kxy,nx,ny,1); int kex = kIndex(kx+halo->lt, ky+halo->up, kf, nx+halo->lt+halo->rt, ny+halo->dn+halo->up, nf); /* Is this correct? Before splitting x- and y- margin widths, the ny argument was ny*nb, which seems weird. */ activity[kex] = gSynSparse[kxy]; } } //resetGSynBuffers_HyPerLayer(getNumNeurons(), getNumChannels(), GSyn[0]); updateReady = false; return PV_SUCCESS; }
// set activity to global x/y/f position, using position in border/margin as required int ShrunkenPatchTestLayer::setActivitytoGlobalPos(){ for (int kLocalExt = 0; kLocalExt < clayer->numExtended; kLocalExt++){ int kxLocalExt = kxPos(kLocalExt, clayer->loc.nx + clayer->loc.halo.lt + clayer->loc.halo.rt, clayer->loc.ny + clayer->loc.halo.dn + clayer->loc.halo.up, clayer->loc.nf) - clayer->loc.halo.lt; int kxGlobalExt = kxLocalExt + clayer->loc.kx0; float xScaleLog2 = clayer->xScale; float x0 = xOriginGlobal(xScaleLog2); float dx = deltaX(xScaleLog2); float x_global_pos = (x0 + dx * kxGlobalExt); int kyLocalExt = kyPos(kLocalExt, clayer->loc.nx + clayer->loc.halo.lt + clayer->loc.halo.rt, clayer->loc.ny + clayer->loc.halo.dn + clayer->loc.halo.up, clayer->loc.nf) - clayer->loc.halo.up; int kyGlobalExt = kyLocalExt + clayer->loc.ky0; bool x_in_local_interior = kxLocalExt >= 0 && kxLocalExt < clayer->loc.nx; bool y_in_local_interior = kyLocalExt >= 0 && kyLocalExt < clayer->loc.ny; bool x_in_global_boundary = kxGlobalExt < 0 || kxGlobalExt >= clayer->loc.nxGlobal; bool y_in_global_boundary = kyGlobalExt < 0 || kyGlobalExt >= clayer->loc.nyGlobal; if( ( x_in_global_boundary || x_in_local_interior ) && ( y_in_global_boundary || y_in_local_interior ) ) { clayer->activity->data[kLocalExt] = x_global_pos; } } return PV_SUCCESS; }
int MoviePvpTestLayer::updateStateWrapper(double time, double dt) { MoviePvp::updateStateWrapper(time, dt); const PVLayerLoc * loc = getLayerLoc(); int nx = loc->nx; int ny = loc->ny; int nf = loc->nf; int nbatch = loc->nbatch; for(int b = 0; b < nbatch; b++){ pvdata_t * dataBatch = data + b * getNumExtended(); int frameIdx; if(strcmp(getBatchMethod(), "byImage") == 0){ frameIdx = (time-1) * nbatch + b; } else if(strcmp(getBatchMethod(), "byMovie") == 0){ frameIdx = b * 2 + (time-1); } for(int nkRes = 0; nkRes < getNumNeurons(); nkRes++){ //Calculate extended index int nkExt = kIndexExtended(nkRes, nx, ny, nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up); //checkVal is the value from batch index 0 pvdata_t checkVal = dataBatch[nkExt]; int kxGlobal = kxPos(nkRes, nx, ny, nf) + loc->kx0; int kyGlobal = kyPos(nkRes, nx, ny, nf) + loc->ky0; int kf = featureIndex(nkRes, nx, ny, nf); pvdata_t expectedVal = kIndex(kxGlobal, kyGlobal, kf, loc->nxGlobal, loc->nyGlobal, nf) + frameIdx*192; if(fabs(checkVal - expectedVal) >= 1e-5){ std::cout << "ImageFileIO " << name << " test Expected: " << expectedVal << " Actual: " << checkVal << "\n"; //exit(-1); } } } return PV_SUCCESS; }
int main(int argc, char* argv[]) { PVLayerLoc loc; int kl, kg; int kx, ky, kf, kxg, kyg, kfg; #ifdef FEATURES_LAST int ij; #endif //printf("size_loc==%ld size_cube==%ld size_ptr==%ld\n", sizeof(PVLayerLoc), sizeof(PVLayerCube), sizeof(pvdata_t*)); //printf("size_int==%ld size_float==%ld, size_size_t==%ld\n", sizeof(int), sizeof(float), sizeof(size_t)); int nf = loc.nf = 3; int nx = loc.nx = 63; int ny = loc.ny = 127; loc.kx0 = 0; loc.ky0 = 0; loc.nxGlobal = nx; loc.nyGlobal = ny; for (kl = 0; kl < nx*ny*nf; kl++) { kg = globalIndexFromLocal_nompi(kl, loc); if (kg != kl) { printf("FAILED:TEST_KG: (kl,kg) = (%d,%d)\n", kl, kg); exit(1); } } // divide in halve by x, take right nf = loc.nf = 2; nx = loc.nx = 32; ny = loc.ny = 128; loc.kx0 = 32; loc.ky0 = 0; loc.nxGlobal = 2.0*nx; loc.nyGlobal = ny; #ifdef FEATURES_LAST for (kf = 0; kf < nf; kf++) { for (ij = 0; ij < nx*ny; ij++) { kl = ij + nx*ny*kf; kx = kxPos(kl, loc.nx, loc.ny, nf); ky = kyPos(kl, loc.nx, loc.ny, nf); kg = globalIndexFromLocal_nompi(kl, loc); kxg = kxPos(kg, loc.nxGlobal, loc.nyGlobal, nf); kyg = kyPos(kg, loc.nxGlobal, loc.nyGlobal, nf); kfg = featureIndex(kg, loc.nxGlobal, loc.nyGlobal, nf); if ((kg-kl) != loc.kx0 + (loc.ky0 + kyg)*loc.nx + kf*nx*ny) { printf("FAILED:TEST_KG: right (kl,kg) = (%d,%d)\n", kl, kg); exit(1); } } } #else for (kl = 0; kl < nx*ny*nf; kl++) { kx = kxPos(kl, loc.nx, loc.ny, nf); ky = kyPos(kl, loc.nx, loc.ny, nf); kf = featureIndex(kl, loc.nx, loc.ny, nf); kg = globalIndexFromLocal_nompi(kl, loc); kxg = kxPos(kg, loc.nxGlobal, loc.nyGlobal, nf); kyg = kyPos(kg, loc.nxGlobal, loc.nyGlobal, nf); kfg = featureIndex(kg, loc.nxGlobal, loc.nyGlobal, nf); assert(loc.kx0+kx == kxg); assert(ky == kyg); assert(kf == kfg); if ((kg-kl) != loc.kx0*nf*(1+ky)) { printf("FAILED:TEST_KG: right (kl,kg) = (%d,%d)\n", kl, kg); exit(1); } } #endif // divide in halve by y, take bottom nf = loc.nf = 5; nx = loc.nx = 32; ny = loc.ny = 128; loc.kx0 = 0; loc.ky0 = 64; loc.nxGlobal = nx; loc.nyGlobal = 2.0*ny; #ifdef FEATURES_LAST for (kf = 0; kf < nf; kf++) { for (ij = 0; ij < nx*ny; ij++) { int kl = ij + nx*ny*kf; int kx = kxPos(kl, loc.nx, loc.ny, nf); int ky = kyPos(kl, loc.nx, loc.ny, nf); kg = globalIndexFromLocal_nompi(kl, loc); kx = kxPos(kg, loc.nxGlobal, loc.nyGlobal, nf); ky = kyPos(kg, loc.nxGlobal, loc.nyGlobal, nf); // kg = ky0*nxGlobal + kf*nxGlobal*nyGlobal // kl = kf*nx*ny if ((kg-kl) != nx*loc.ky0 + kf*nx*(loc.nyGlobal - ny)) { printf("FAILED:TEST_KG: bottom (kl,kg) = (%d,%d)\n", kl, kg); exit(1); } } } #else for (kl = 0; kl < nx*ny*nf; kl++) { kx = kxPos(kl, loc.nx, loc.ny, nf); ky = kyPos(kl, loc.nx, loc.ny, nf); kf = featureIndex(kl, loc.nx, loc.ny, nf); kg = globalIndexFromLocal_nompi(kl, loc); kxg = kxPos(kg, loc.nxGlobal, loc.nyGlobal, nf); kyg = kyPos(kg, loc.nxGlobal, loc.nyGlobal, nf); kfg = featureIndex(kg, loc.nxGlobal, loc.nyGlobal, nf); assert(loc.kx0+kx == kxg); assert(loc.ky0+ky == kyg); assert(kf == kfg); if ((kg-kl) != loc.ky0*nf*nx) { printf("FAILED:TEST_KG: bottom (kl,kg) = (%d,%d)\n", kl, kg); exit(1); } } #endif nf = loc.nf = 1; nx = loc.nx = 4096; ny = loc.ny = 4096+1; // this should fail (probably not now with ints) ny = loc.ny = 4096; loc.kx0 = 0; loc.ky0 = 0; loc.nxGlobal = nx; loc.nyGlobal = ny; for (kl = 0; kl < nx*ny*nf; kl++) { kg = globalIndexFromLocal_nompi(kl, loc); if (kg != kl) { printf("FAILED:TEST_KG: max ny (kl,kg) = (%d,%d)\n", kl, kg); exit(1); } } return 0; }
int TransposePoolingConn::deliverPresynapticPerspective(PVLayerCube const * activity, int arborID) { //Check if we need to update based on connection's channel if(getChannel() == CHANNEL_NOUPDATE){ return PV_SUCCESS; } assert(post->getChannel(getChannel())); const PVLayerLoc * preLoc = preSynapticLayer()->getLayerLoc(); const PVLayerLoc * postLoc = postSynapticLayer()->getLayerLoc(); assert(arborID >= 0); const int numExtended = activity->numItems; //Grab postIdxLayer's data int* postIdxData = NULL; if(pvpatchAccumulateType == ACCUMULATE_MAXPOOLING){ PoolingIndexLayer* postIndexLayer = originalConn->getPostIndexLayer(); assert(postIndexLayer); //Make sure this layer is an integer layer assert(postIndexLayer->getDataType() == PV_INT); DataStore * store = parent->icCommunicator()->publisherStore(postIndexLayer->getLayerId()); int delay = getDelay(arborID); //TODO this is currently a hack, need to properly implement data types. postIdxData = (int*) store->buffer(LOCAL, delay); } for(int b = 0; b < parent->getNBatch(); b++){ pvdata_t * activityBatch = activity->data + b * (preLoc->nx + preLoc->halo.rt + preLoc->halo.lt) * (preLoc->ny + preLoc->halo.up + preLoc->halo.dn) * preLoc->nf; pvdata_t * gSynPatchHeadBatch = post->getChannel(getChannel()) + b * postLoc->nx * postLoc->ny * postLoc->nf; int * postIdxDataBatch = NULL; if(pvpatchAccumulateType == ACCUMULATE_MAXPOOLING){ postIdxDataBatch = postIdxData + b * originalConn->getPostIndexLayer()->getNumExtended(); } unsigned int * activeIndicesBatch = NULL; if(activity->isSparse){ activeIndicesBatch = activity->activeIndices + b * (preLoc->nx + preLoc->halo.rt + preLoc->halo.lt) * (preLoc->ny + preLoc->halo.up + preLoc->halo.dn) * preLoc->nf; } int numLoop; if(activity->isSparse){ numLoop = activity->numActive[b]; } else{ numLoop = numExtended; } #ifdef PV_USE_OPENMP_THREADS //Clear all thread gsyn buffer if(thread_gSyn){ int numNeurons = post->getNumNeurons(); #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for(int i = 0; i < parent->getNumThreads() * numNeurons; i++){ int ti = i/numNeurons; int ni = i % numNeurons; thread_gSyn[ti][ni] = 0; } } #endif // PV_USE_OPENMP_THREADS #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for schedule(static) #endif for (int loopIndex = 0; loopIndex < numLoop; loopIndex++) { int kPreExt; if(activity->isSparse){ kPreExt = activeIndicesBatch[loopIndex]; } else{ kPreExt = loopIndex; } float a = activityBatch[kPreExt]; if (a == 0.0f) continue; //If we're using thread_gSyn, set this here pvdata_t * gSynPatchHead; #ifdef PV_USE_OPENMP_THREADS if(thread_gSyn){ int ti = omp_get_thread_num(); gSynPatchHead = thread_gSyn[ti]; } else{ gSynPatchHead = gSynPatchHeadBatch; } #else // PV_USE_OPENMP_THREADS gSynPatchHead = gSynPatchHeadBatch; #endif // PV_USE_OPENMP_THREADS const int kxPreExt = kxPos(kPreExt, preLoc->nx + preLoc->halo.lt + preLoc->halo.rt, preLoc->ny + preLoc->halo.dn + preLoc->halo.up, preLoc->nf); const int kyPreExt = kyPos(kPreExt, preLoc->nx + preLoc->halo.lt + preLoc->halo.rt, preLoc->ny + preLoc->halo.dn + preLoc->halo.up, preLoc->nf); const int kfPre = featureIndex(kPreExt, preLoc->nx + preLoc->halo.lt + preLoc->halo.rt, preLoc->ny + preLoc->halo.dn + preLoc->halo.up, preLoc->nf); if(pvpatchAccumulateType == ACCUMULATE_MAXPOOLING){ const int kxPreGlobalExt = kxPreExt + preLoc->kx0; const int kyPreGlobalExt = kyPreExt + preLoc->ky0; if(kxPreGlobalExt < preLoc->halo.lt || kxPreGlobalExt >= preLoc->nxGlobal + preLoc->halo.lt || kyPreGlobalExt < preLoc->halo.up || kyPreGlobalExt >= preLoc->nyGlobal + preLoc->halo.up){ continue; } //Convert stored global extended index into local extended index int postGlobalExtIdx = postIdxDataBatch[kPreExt]; // If all inputs are zero and input layer is sparse, postGlobalExtIdx will still be -1. if(postGlobalExtIdx == -1) { continue; } //Make sure the index is in bounds assert(postGlobalExtIdx >= 0 && postGlobalExtIdx < (postLoc->nxGlobal + postLoc->halo.lt + postLoc->halo.rt) * (postLoc->nyGlobal + postLoc->halo.up + postLoc->halo.dn) * postLoc->nf); const int kxPostGlobalExt = kxPos(postGlobalExtIdx, postLoc->nxGlobal + postLoc->halo.lt + postLoc->halo.rt, postLoc->nyGlobal + postLoc->halo.dn + postLoc->halo.up, postLoc->nf); const int kyPostGlobalExt = kyPos(postGlobalExtIdx, postLoc->nxGlobal + postLoc->halo.lt + postLoc->halo.rt, postLoc->nyGlobal + postLoc->halo.dn + postLoc->halo.up, postLoc->nf); const int kfPost = featureIndex(postGlobalExtIdx, postLoc->nxGlobal + postLoc->halo.lt + postLoc->halo.rt, postLoc->nyGlobal + postLoc->halo.dn + postLoc->halo.up, postLoc->nf); const int kxPostLocalRes = kxPostGlobalExt - postLoc->kx0 - postLoc->halo.lt; const int kyPostLocalRes = kyPostGlobalExt - postLoc->ky0 - postLoc->halo.up; if(kxPostLocalRes < 0 || kxPostLocalRes >= postLoc->nx|| kyPostLocalRes < 0 || kyPostLocalRes >= postLoc->ny){ continue; } const int kPostLocalRes = kIndex(kxPostLocalRes, kyPostLocalRes, kfPost, postLoc->nx, postLoc->ny, postLoc->nf); gSynPatchHeadBatch[kPostLocalRes] = a; } else{ PVPatch * weights = getWeights(kPreExt, arborID); const int nk = weights->nx * fPatchSize(); const int ny = weights->ny; pvgsyndata_t * postPatchStart = gSynPatchHead + getGSynPatchStart(kPreExt, arborID); const int sy = getPostNonextStrides()->sy; // stride in layer int offset = kfPre; int sf = fPatchSize(); pvwdata_t w = 1.0; if(getPvpatchAccumulateType() == ACCUMULATE_SUMPOOLING){ float relative_XScale = pow(2, (post->getXScale() - pre->getXScale())); float relative_YScale = pow(2, (post->getYScale() - pre->getYScale())); w = 1.0/(nxp*nyp*relative_XScale*relative_YScale); } void* auxPtr = NULL; for (int y = 0; y < ny; y++) { (accumulateFunctionPointer)(0, nk, postPatchStart + y*sy + offset, a, &w, auxPtr, sf); } } } #ifdef PV_USE_OPENMP_THREADS //Set back into gSyn if(thread_gSyn){ pvdata_t * gSynPatchHead = gSynPatchHeadBatch; int numNeurons = post->getNumNeurons(); //Looping over neurons first to be thread safe #pragma omp parallel for for(int ni = 0; ni < numNeurons; ni++){ for(int ti = 0; ti < parent->getNumThreads(); ti++){ if(pvpatchAccumulateType == ACCUMULATE_MAXPOOLING){ if(gSynPatchHead[ni] < fabs(thread_gSyn[ti][ni])){ gSynPatchHead[ni] = thread_gSyn[ti][ni]; } } else{ gSynPatchHead[ni] += thread_gSyn[ti][ni]; } } } } #endif } return PV_SUCCESS; }
//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 PursuitLayer::recvSynapticInput(HyPerConn * conn, const PVLayerCube * activity, int arborID) { if (parent->simulationTime()<nextUpdate) return PV_SUCCESS; nextUpdate += updatePeriod; recvsyn_timer->start(); assert(arborID >= 0); if (conn->usingSharedWeights() == false) { fprintf(stderr, "Error: PursuitLayer can only be the postsynaptic layer of a connection using shared weights (this condition should be removed eventually).\n"); abort(); } HyPerLayer * pre = conn->preSynapticLayer(); const PVLayerLoc * pre_loc = pre->getLayerLoc(); if (pre_loc->nx != getLayerLoc()->nx || pre_loc->ny != getLayerLoc()->ny) { fprintf(stderr, "Error: PursuitLayer requires incoming connections to be one-to-one.\n"); abort(); } #ifdef DEBUG_OUTPUT int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); //printf("[%d]: HyPerLayr::recvSyn: neighbor=%d num=%d actv=%p this=%p conn=%p\n", rank, neighbor, numExtended, activity, this, conn); printf("[%d]: HyPerLayr::recvSyn: neighbor=%d num=%d actv=%p this=%p conn=%p\n", rank, 0, numExtended, activity, this, conn); fflush(stdout); #endif // DEBUG_OUTPUT const int numExtended = activity->numItems; for (int kPre = 0; kPre < numExtended; kPre++) { float a = activity->data[kPre]; if (a == 0.0f) continue; PVPatch * weights = conn->getWeights(kPre, arborID); // WARNING - assumes every value in weights maps into a valid value in GSyn // - assumes patch stride sf is 1 int nk = conn->fPatchSize() * weights->nx; int ny = weights->ny; int sy = conn->getPostNonextStrides()->sy; // stride in layer int syw = conn->yPatchStride(); // stride in patch pvdata_t * gSynPatchHead = this->getChannel(conn->getChannel()); pvdata_t * gSynPatchStart = gSynPatchHead + conn->getGSynPatchStart(kPre, arborID); pvwdata_t * data = conn->get_wData(arborID,kPre); for (int y = 0; y < ny; y++) { (conn->accumulateFunctionPointer)(nk, gSynPatchStart + y*sy, a, data + y*syw, NULL); } } // Set |w(:,:,f)|^2. Since this is a one-to-one connection with one presynaptic feature, // only have to do once for each feature of a single (x,y) site and then copy. int nxp = conn->xPatchSize(); int nyp = conn->yPatchSize(); int nfp = conn->fPatchSize(); int num_weights = nxp*nyp*nfp; assert(zUnitCellSize(pre->getXScale(), getXScale())==1); assert(zUnitCellSize(pre->getYScale(), getYScale())==1); assert(conn->getNumDataPatches()==1); for (int kf=0; kf<nfp; kf++) { pvwdata_t * weight = conn->get_wDataHead(arborID, 0); pvdata_t sum = 0.0; for (int k=0; k<num_weights; k+=nfp) { pvwdata_t w = weight[k + kf]; // Assumes stride in features is 1. //TODO-CER-2014.4.4 - convert weights sum += w*w; } wnormsq[kf] = sum; } pvdata_t * gSynStart = GSyn[conn->getChannel()]; int nx = getLayerLoc()->nx; int ny = getLayerLoc()->ny; int nxy = nx*ny; // TODO: Can I compute energyDropsBestFeature and minLocationsBestFeature without storing all the energyDrops and minimumLocations? for (int kxy=0; kxy<nxy; kxy++) { for (int kf=0; kf<nfp; kf++) { int k=kxy*nfp+kf; // Assumes stride in features is 1. minimumLocations[k] = gSynStart[k]/wnormsq[kf]; energyDrops[k] = -gSynStart[k]*minimumLocations[k]/2; } } for (int kxy=0; kxy<nxy; kxy++) { minFeatures[kxy] = -1; energyDropsBestFeature[kxy] = FLT_MAX; int index0 = kxy*nfp; // assumes stride in features is 1. if (foundFeatures[kxy]>=0) { energyDropsBestFeature[kxy] = energyDrops[kxy*nfp+foundFeatures[kxy]]; minFeatures[kxy] = foundFeatures[kxy]; } else { for (int kf=0; kf<nfp; kf++) { if (energyDrops[index0+kf] < energyDropsBestFeature[kxy]) { minFeatures[kxy] = kf; energyDropsBestFeature[kxy] = energyDrops[index0+kf]; } } } } for (int kxy=0; kxy<nxy; kxy++) { assert(minFeatures[kxy]>=0 && minFeatures[kxy]<nfp); int baseindex = kxy*nfp; minLocationsBestFeature[kxy] = minimumLocations[baseindex+minFeatures[kxy]]; } bool mask[nxy]; memset(mask, false, nxy*sizeof(*mask)); pvdata_t smallestEnergyDrop; int minloc; while (constrainMinima(), minloc = filterMinEnergies(mask, &smallestEnergyDrop), smallestEnergyDrop<FLT_MAX) { assert(foundFeatures[minloc]<0 || foundFeatures[minloc]==minFeatures[minloc]); foundFeatures[minloc] = minFeatures[minloc]; gSynSparse[minloc] += minLocationsBestFeature[minloc]; if (gSynSparse[minloc] < 1e-4) { gSynSparse[minloc]=0; foundFeatures[minloc] = -1; } int minlocx = kxPos(minloc,nx,ny,1); int maskstartx = minlocx-(nxp-1); if (maskstartx<0) maskstartx=0; int maskstopx = minlocx+nxp; if (maskstopx>nx) maskstopx=nx; int minlocy = kyPos(minloc,nx,ny,1); int maskstarty = minlocy-(nyp-1); if (maskstarty<0) maskstarty=0; int maskstopy = minlocy+nyp; if (maskstopy>ny) maskstopy=ny; for (int ky=maskstarty; ky<maskstopy; ky++) { for (int kx=maskstartx; kx<maskstopx; kx++) { mask[kIndex(kx,ky,0,nx,ny,1)]=true; } } } recvsyn_timer->stop(); updateReady = true; return 0; }
int main(int argc, char* argv[]) { int kl; int nf = 3; float nx = 64; float ny = 128; float nxLocal = nx; float nyLocal = ny; int inx = (int) nx; int iny = (int) ny; for (kl = 0; kl < inx*iny*nf; kl++) { #ifdef FEATURES_LAST int kk = (kl/inx) % iny; #else int kk = kl/(nf*nx); #endif float ky = kyPos(kl, nxLocal, nyLocal, nf); if (ky != (float)kk) { printf("FAILED:TEST_KYPOS: (k,ky) = (%d,%f)\n", kl, ky); exit(1); } } nx = 13; ny = 2007; nxLocal = nx; nyLocal = ny; inx = nx; iny = ny; for (kl = 0; kl < inx*iny*nf; kl++) { #ifdef FEATURES_LAST int kk = (kl/inx) % iny; #else int kk = kl/(nf*nx); #endif float ky = kyPos(kl, nxLocal, nyLocal, nf); if ((int)ky-kk != 0) { printf("FAILED:TEST_KYPOS: (k,ky) = (%d,%f)\n", kl, ky); exit(1); } } nf = 4; nx = 5; ny = 107; nxLocal = nx; nyLocal = ny; inx = nx; iny = ny; for (kl = 0; kl < inx*iny*nf; kl++) { #ifdef FEATURES_LAST int kk = (kl/inx) % iny; #else int kk = kl/(nf*nx); #endif float ky = kyPos(kl, nxLocal, nyLocal, nf); if ((int)ky-kk != 0) { printf("FAILED:TEST_KYPOS: (k,ky) = (%d,%f)\n", kl, ky); exit(1); } } nf = 1; nx = 1; ny = 16777216+2; // this should fail for FEATURES_LAST ny = 16777216; nxLocal = nx; nyLocal = ny; inx = nx; iny = ny; for (kl = 0; kl < inx*iny*nf; kl++) { #ifdef FEATURES_LAST int kk = (kl/inx) % iny; #else int kk = kl/(nf*nx); #endif float ky = kyPos(kl, nxLocal, nyLocal, nf); if ((int)ky-kk != 0) { printf("FAILED:TEST_KYPOS: (k,ky) = (%d,%f)\n", kl, ky); exit(1); } } return 0; }
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 PoolingConn::deliverPostsynapticPerspective(PVLayerCube const * activity, int arborID) { //Check channel number for noupdate if(getChannel() == CHANNEL_NOUPDATE) { return PV_SUCCESS; } assert(post->getChannel(getChannel())); assert(arborID >= 0); //Get number of neurons restricted target const int numPostRestricted = post->getNumNeurons(); float dt_factor = getConvertToRateDeltaTimeFactor(); const PVLayerLoc * sourceLoc = preSynapticLayer()->getLayerLoc(); const PVLayerLoc * targetLoc = post->getLayerLoc(); const int sourceNx = sourceLoc->nx; const int sourceNy = sourceLoc->ny; const int sourceNf = sourceLoc->nf; const int targetNx = targetLoc->nx; const int targetNy = targetLoc->ny; const int targetNf = targetLoc->nf; const PVHalo * sourceHalo = &sourceLoc->halo; const PVHalo * targetHalo = &targetLoc->halo; //get source layer's extended y stride int sy = (sourceNx+sourceHalo->lt+sourceHalo->rt)*sourceNf; //The start of the gsyn buffer pvdata_t * gSynPatchHead = post->getChannel(this->getChannel()); clearGateIdxBuffer(); int* gatePatchHead = NULL; if(needPostIndexLayer) { gatePatchHead = postIndexLayer->getChannel(CHANNEL_EXC); } long * startSourceExtBuf = getPostToPreActivity(); if(!startSourceExtBuf) { std::cout << "HyPerLayer::recvFromPost error getting preToPostActivity from connection. Is shrink_patches on?\n"; exit(EXIT_FAILURE); } float resetVal = 0; if(getPvpatchAccumulateType() == ACCUMULATE_MAXPOOLING) { resetVal = -INFINITY; } for(int b = 0; b < parent->getNBatch(); b++) { #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for (int kTargetRes = 0; kTargetRes < numPostRestricted; kTargetRes++) { pvdata_t * activityBatch = activity->data + b * (sourceNx + sourceHalo->rt + sourceHalo->lt) * (sourceNy + sourceHalo->up + sourceHalo->dn) * sourceNf; pvdata_t * gSynPatchHeadBatch = gSynPatchHead + b * targetNx * targetNy * targetNf; //Change restricted to extended post neuron int kTargetExt = kIndexExtended(kTargetRes, targetNx, targetNy, targetNf, targetHalo->lt, targetHalo->rt, targetHalo->dn, targetHalo->up); //Read from buffer long startSourceExt = startSourceExtBuf[kTargetRes]; //Calculate target's start of gsyn pvdata_t * gSynPatchPos = gSynPatchHeadBatch + kTargetRes; //Initialize patch as a huge negative number *gSynPatchPos = resetVal; int* gatePatchPos = NULL; if(needPostIndexLayer) { gatePatchPos = gatePatchHead + b * postIndexLayer->getNumNeurons() + kTargetRes; //Initialize gatePatchPos as a negative number *gatePatchPos = -1; } float* activityStartBuf = &(activityBatch[startSourceExt]); pvwdata_t * weightY = NULL; //No weights in pooling int sf = postConn->fPatchSize(); int yPatchSize = postConn->yPatchSize(); int numPerStride = postConn->xPatchSize() * postConn->fPatchSize(); const PVLayerLoc * postLoc = post->getLayerLoc(); const int kfPost = featureIndex(kTargetExt, postLoc->nx + postLoc->halo.lt + postLoc->halo.rt, postLoc->ny + postLoc->halo.dn + postLoc->halo.up, postLoc->nf); int offset = kfPost; pvwdata_t w = 1.0; if(getPvpatchAccumulateType() == ACCUMULATE_SUMPOOLING) { float relative_XScale = pow(2, (post->getXScale() - pre->getXScale())); float relative_YScale = pow(2, (post->getYScale() - pre->getYScale())); w = 1.0/(nxp*nyp*relative_XScale*relative_YScale); } for (int ky = 0; ky < yPatchSize; ky++) { int kPreExt = startSourceExt + ky*sy+offset; const int kxPreExt = kxPos(kPreExt, sourceLoc->nx + sourceLoc->halo.lt + sourceLoc->halo.rt, sourceLoc->ny + sourceLoc->halo.dn + sourceLoc->halo.up, sourceLoc->nf); const int kyPreExt = kyPos(kPreExt, sourceLoc->nx + sourceLoc->halo.lt + sourceLoc->halo.rt, sourceLoc->ny + sourceLoc->halo.dn + sourceLoc->halo.up, sourceLoc->nf); const int kfPre = featureIndex(kPreExt, sourceLoc->nx + sourceLoc->halo.lt + sourceLoc->halo.rt, sourceLoc->ny + sourceLoc->halo.dn + sourceLoc->halo.up, sourceLoc->nf); const int kxPreGlobalExt = kxPreExt + sourceLoc->kx0; const int kyPreGlobalExt = kyPreExt + sourceLoc->ky0; const int kPreGlobalExt = kIndex(kxPreGlobalExt, kyPreGlobalExt, kfPre, sourceLoc->nxGlobal + sourceLoc->halo.lt + sourceLoc->halo.rt, sourceLoc->nyGlobal + sourceLoc->halo.up + sourceLoc->halo.dn, sourceLoc->nf); float * activityY = &(activityStartBuf[ky*sy+offset]); (accumulateFunctionFromPostPointer)(kPreGlobalExt, numPerStride, gSynPatchPos, activityY, &w, dt_factor, gatePatchPos, sf); } } } return PV_SUCCESS; }
int PoolingConn::deliverPresynapticPerspective(PVLayerCube const * activity, int arborID) { //Check if we need to update based on connection's channel if(getChannel() == CHANNEL_NOUPDATE) { return PV_SUCCESS; } assert(post->getChannel(getChannel())); float dt_factor; if (getPvpatchAccumulateType()==ACCUMULATE_STOCHASTIC) { dt_factor = getParent()->getDeltaTime(); } else { dt_factor = getConvertToRateDeltaTimeFactor(); } const PVLayerLoc * preLoc = preSynapticLayer()->getLayerLoc(); const PVLayerLoc * postLoc = postSynapticLayer()->getLayerLoc(); assert(arborID >= 0); const int numExtended = activity->numItems; float resetVal = 0; if(getPvpatchAccumulateType() == ACCUMULATE_MAXPOOLING) { resetVal = -INFINITY; float* gSyn = post->getChannel(getChannel()); //gSyn is res #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for(int i = 0; i < post->getNumNeuronsAllBatches(); i++) { gSyn[i] = resetVal; } } clearGateIdxBuffer(); for(int b = 0; b < parent->getNBatch(); b++) { pvdata_t * activityBatch = activity->data + b * (preLoc->nx + preLoc->halo.rt + preLoc->halo.lt) * (preLoc->ny + preLoc->halo.up + preLoc->halo.dn) * preLoc->nf; pvdata_t * gSynPatchHeadBatch = post->getChannel(getChannel()) + b * postLoc->nx * postLoc->ny * postLoc->nf; int* gatePatchHeadBatch = NULL; if(needPostIndexLayer) { gatePatchHeadBatch = postIndexLayer->getChannel(CHANNEL_EXC) + b * postIndexLayer->getNumNeurons(); } unsigned int * activeIndicesBatch = NULL; if(activity->isSparse) { activeIndicesBatch = activity->activeIndices + b * (preLoc->nx + preLoc->halo.rt + preLoc->halo.lt) * (preLoc->ny + preLoc->halo.up + preLoc->halo.dn) * preLoc->nf; } int numLoop; if(activity->isSparse) { numLoop = activity->numActive[b]; } else { numLoop = numExtended; } if(thread_gateIdxBuffer) { #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for(int i = 0; i < parent->getNumThreads() * post->getNumNeurons(); i++) { int ti = i/post->getNumNeurons(); int ni = i % post->getNumNeurons(); thread_gateIdxBuffer[ti][ni] = -1; } } #ifdef PV_USE_OPENMP_THREADS //Clear all gsyn buffers if(thread_gSyn) { int numNeurons = post->getNumNeurons(); #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for(int i = 0; i < parent->getNumThreads() * numNeurons; i++) { int ti = i/numNeurons; int ni = i % numNeurons; thread_gSyn[ti][ni] = resetVal; } } #endif // PV_USE_OPENMP_THREADS #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for schedule(static) #endif for (int loopIndex = 0; loopIndex < numLoop; loopIndex++) { int kPreExt; if(activity->isSparse) { kPreExt = activeIndicesBatch[loopIndex]; } else { kPreExt = loopIndex; } float a = activityBatch[kPreExt] * dt_factor; //if (a == 0.0f) continue; //If we're using thread_gSyn, set this here pvdata_t * gSynPatchHead; //float * gatePatchHead = NULL; int * gatePatchHead = NULL; #ifdef PV_USE_OPENMP_THREADS if(thread_gSyn) { int ti = omp_get_thread_num(); gSynPatchHead = thread_gSyn[ti]; } else { gSynPatchHead = gSynPatchHeadBatch; } if(needPostIndexLayer) { if(thread_gateIdxBuffer) { int ti = omp_get_thread_num(); gatePatchHead = thread_gateIdxBuffer[ti]; } else { gatePatchHead = gatePatchHeadBatch; } } #else // PV_USE_OPENMP_THREADS gSynPatchHead = gSynPatchHeadBatch; if(needPostIndexLayer) { gatePatchHead = gatePatchHeadBatch; } #endif // PV_USE_OPENMP_THREADS //deliverOnePreNeuronActivity(kPreExt, arborID, a, gSynPatchHead, gatePatchHead); PVPatch * weights = getWeights(kPreExt, arborID); const int nk = weights->nx * fPatchSize(); const int ny = weights->ny; const int sy = getPostNonextStrides()->sy; // stride in layer pvwdata_t * weightDataStart = NULL; pvgsyndata_t * postPatchStart = gSynPatchHead + getGSynPatchStart(kPreExt, arborID); int* postGatePatchStart = gatePatchHead + getGSynPatchStart(kPreExt, arborID); //float* postGatePatchStart = gatePatchHead + getGSynPatchStart(kPreExt, arborID); const int kxPreExt = kxPos(kPreExt, preLoc->nx + preLoc->halo.lt + preLoc->halo.rt, preLoc->ny + preLoc->halo.dn + preLoc->halo.up, preLoc->nf); const int kyPreExt = kyPos(kPreExt, preLoc->nx + preLoc->halo.lt + preLoc->halo.rt, preLoc->ny + preLoc->halo.dn + preLoc->halo.up, preLoc->nf); const int kfPre = featureIndex(kPreExt, preLoc->nx + preLoc->halo.lt + preLoc->halo.rt, preLoc->ny + preLoc->halo.dn + preLoc->halo.up, preLoc->nf); const int kxPreGlobalExt = kxPreExt + preLoc->kx0; const int kyPreGlobalExt = kyPreExt + preLoc->ky0; const int kPreGlobalExt = kIndex(kxPreGlobalExt, kyPreGlobalExt, kfPre, preLoc->nxGlobal + preLoc->halo.lt + preLoc->halo.rt, preLoc->nyGlobal + preLoc->halo.up + preLoc->halo.dn, preLoc->nf); int offset = kfPre; int sf = fPatchSize(); pvwdata_t w = 1.0; if(getPvpatchAccumulateType() == ACCUMULATE_SUMPOOLING) { float relative_XScale = pow(2, (post->getXScale() - pre->getXScale())); float relative_YScale = pow(2, (post->getYScale() - pre->getYScale())); w = 1.0/(nxp*nyp*relative_XScale*relative_YScale); } void* auxPtr = NULL; for (int y = 0; y < ny; y++) { if(needPostIndexLayer) { auxPtr = (postGatePatchStart+ y*sy + offset); } (accumulateFunctionPointer)(kPreGlobalExt, nk, postPatchStart + y*sy + offset, a, &w, auxPtr, sf); } } #ifdef PV_USE_OPENMP_THREADS //Accumulate back into gSyn // Should this be done in HyPerLayer where it can be done once, as opposed to once per connection? if(thread_gSyn) { pvdata_t * gSynPatchHead = gSynPatchHeadBatch; //float* gateIdxBuffer = postIndexLayer->getChannel(CHANNEL_EXC); int * gateIdxBuffer = NULL; if(needPostIndexLayer && thread_gateIdxBuffer) { gateIdxBuffer = gatePatchHeadBatch; } int numNeurons = post->getNumNeurons(); //Looping over neurons first to be thread safe #pragma omp parallel for for(int ni = 0; ni < numNeurons; ni++) { //Different for maxpooling if(getPvpatchAccumulateType() == ACCUMULATE_MAXPOOLING) { for(int ti = 0; ti < parent->getNumThreads(); ti++) { if(gSynPatchHead[ni] < thread_gSyn[ti][ni]) { gSynPatchHead[ni] = thread_gSyn[ti][ni]; if(needPostIndexLayer && thread_gateIdxBuffer) { gateIdxBuffer[ni] = thread_gateIdxBuffer[ti][ni]; assert(gateIdxBuffer >= 0); } } } } else { for(int ti = 0; ti < parent->getNumThreads(); ti++) { gSynPatchHead[ni] += thread_gSyn[ti][ni]; } } } } #endif } if(activity->isSparse) { pvdata_t * gSyn = post->getChannel(getChannel()); for (int k=0; k<post->getNumNeuronsAllBatches(); k++) { if (gSyn[k]==-INFINITY) { gSyn[k] = 0.0f; } } } return PV_SUCCESS; }
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; }
/** * @timef * NOTES: * - kPost, kxPost, kyPost are indices in the restricted post-synaptic layer. * */ int PostConnProbe::outputState(double timef) { int k, kxPre, kyPre; HyPerConn * c = getTargetHyPerConn(); PVPatch * w; PVPatch *** wPost = c->convertPreSynapticWeights(timef); // TODO - WARNING: currently only works if nfPre==0 const PVLayer * lPre = c->preSynapticLayer()->clayer; const PVLayer * lPost = c->postSynapticLayer()->clayer; const int nxPre = lPre->loc.nx; const int nyPre = lPre->loc.ny; const int nfPre = lPre->loc.nf; const PVHalo * haloPre = &lPre->loc.halo; const int nxPost = lPost->loc.nx; const int nyPost = lPost->loc.ny; const int nfPost = lPost->loc.nf; const PVHalo * haloPost = &lPost->loc.halo; // calc kPost if needed if (kPost < 0) { kPost = kIndex(kxPost, kyPost, kfPost, nxPost, nyPost, nfPost); } else { kxPost = kxPos(kPost, nxPost, nyPost, nfPost); kyPost = kyPos(kPost, nxPost, nyPost, nfPost); kfPost = featureIndex(kPost, nxPost, nyPost, nfPost); } c->preSynapticPatchHead(kxPost, kyPost, kfPost, &kxPre, &kyPre); const int kxPreEx = kxPre + haloPre->lt; const int kyPreEx = kyPre + haloPre->up; const int kxPostEx = kxPost + haloPost->lt; const int kyPostEx = kyPost + haloPost->up; const int kPostEx = kIndex(kxPostEx, kyPostEx, kfPost, nxPost+haloPost->lt+haloPost->rt, nyPost+haloPost->dn+haloPost->up, nfPost); const bool postFired = lPost->activity->data[kPostEx] > 0.0; w = wPost[getArborID()][kPost]; pvwdata_t * wPostData = c->getWPostData(getArborID(),kPost); const int nw = w->nx * w->ny * nfPost; //w->nf; if (wPrev == NULL) { wPrev = (pvwdata_t *) calloc(nw, sizeof(pvwdata_t)); for (k = 0; k < nw; k++) { wPrev[k] = wPostData[k]; // This is broken if the patch is shrunken } } if (wActiv == NULL) { wActiv = (pvwdata_t *) calloc(nw, sizeof(pvwdata_t)); } k = 0; for (int ky = 0; ky < w->ny; ky++) { for (int kx = 0; kx < w->nx; kx++) { int kPre = kIndex(kx+kxPreEx, ky+kyPreEx, 0, nxPre+haloPre->lt+haloPre->rt, nyPre+haloPre->dn+haloPre->up, nfPre); wActiv[k++] = lPre->activity->data[kPre]; } } bool changed = false; for (k = 0; k < nw; k++) { if (wPrev[k] != wPostData[k] || wActiv[k] != 0.0) { changed = true; break; } } FILE * fp = getStream()->fp; if (stdpVars && (postFired || changed)) { if (postFired) fprintf(fp, "*"); else fprintf(fp, " "); fprintf(fp, "t=%.1f w%d(%d,%d,%d) prePatchHead(%d,%d): ", timef, kPost, kxPost, kyPost, kfPost, kxPre, kyPre); if (image) fprintf(fp, "tag==%d ", image->tag()); fprintf(fp, "\n"); } if (stdpVars && changed) { text_write_patch_extra(fp, w, wPostData, wPrev, wActiv, getTargetHyPerConn()); fflush(fp); } for (k = 0; k < nw; k++) { wPrev[k] = wPostData[k]; } if (outputIndices) { fprintf(fp, "w%d(%d,%d,%d) prePatchHead(%d,%d): ", kPost, kxPost, kyPost, kfPost, kxPre, kyPre); if(!stdpVars){ fprintf(fp,"\n"); } const PVLayer * lPre = c->preSynapticLayer()->clayer; write_patch_indices(fp, w, &lPre->loc, kxPre, kyPre, 0); fflush(fp); } return 0; }