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; }
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; }