PetaVision  Alpha
L0NormProbe.cpp
1 /*
2  * L0NormProbe.cpp
3  *
4  * Created on: Aug 11, 2015
5  * Author: pschultz
6  */
7 
8 #include "L0NormProbe.hpp"
9 #include "columns/HyPerCol.hpp"
10 #include "layers/HyPerLayer.hpp"
11 
12 namespace PV {
13 
14 L0NormProbe::L0NormProbe() : AbstractNormProbe() { initialize_base(); }
15 
16 L0NormProbe::L0NormProbe(const char *name, HyPerCol *hc) : AbstractNormProbe() {
17  initialize_base();
18  initialize(name, hc);
19 }
20 
21 L0NormProbe::~L0NormProbe() {}
22 
23 int L0NormProbe::initialize(const char *name, HyPerCol *hc) {
24  return AbstractNormProbe::initialize(name, hc);
25 }
26 
27 int L0NormProbe::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
28  int status = AbstractNormProbe::ioParamsFillGroup(ioFlag);
29  ioParam_nnzThreshold(ioFlag);
30  return status;
31 }
32 
33 void L0NormProbe::ioParam_nnzThreshold(enum ParamsIOFlag ioFlag) {
34  parent->parameters()->ioParamValue(ioFlag, getName(), "nnzThreshold", &nnzThreshold, (float)0);
35 }
36 
37 double L0NormProbe::getValueInternal(double timevalue, int index) {
38  if (index < 0 || index >= parent->getNBatch()) {
39  return PV_FAILURE;
40  }
41  PVLayerLoc const *loc = getTargetLayer()->getLayerLoc();
42  int const nx = loc->nx;
43  int const ny = loc->ny;
44  int const nf = loc->nf;
45  PVHalo const *halo = &loc->halo;
46  int const lt = halo->lt;
47  int const rt = halo->rt;
48  int const dn = halo->dn;
49  int const up = halo->up;
50  int sum = 0;
51  float const *aBuffer =
52  getTargetLayer()->getLayerData() + index * getTargetLayer()->getNumExtended();
53 
54  if (getMaskLayer()) {
55  PVLayerLoc const *maskLoc = getMaskLayer()->getLayerLoc();
56  PVHalo const *maskHalo = &maskLoc->halo;
57  float const *maskLayerData =
59  + index * getMaskLayer()->getNumExtended(); // Is there a DataStore method to return the
60  // part of the layer data for a given batch
61  // index?
62  int const maskLt = maskHalo->lt;
63  int const maskRt = maskHalo->rt;
64  int const maskDn = maskHalo->dn;
65  int const maskUp = maskHalo->up;
66  if (maskHasSingleFeature()) {
67  assert(getTargetLayer()->getNumNeurons() == nx * ny * nf);
68  int nxy = nx * ny;
69 #ifdef PV_USE_OPENMP_THREADS
70 #pragma omp parallel for reduction(+ : sum)
71 #endif // PV_USE_OPENMP_THREADS
72  for (int kxy = 0; kxy < nxy; kxy++) {
73  int kexMask = kIndexExtended(kxy, nx, ny, 1, maskLt, maskRt, maskDn, maskUp);
74  if (maskLayerData[kexMask]) {
75  int featureBase = kxy * nf;
76  for (int f = 0; f < nf; f++) {
77  int kex = kIndexExtended(featureBase++, nx, ny, nf, lt, rt, dn, up);
78  float val = fabsf(aBuffer[kex]);
79  sum += val > nnzThreshold;
80  }
81  }
82  }
83  }
84  else {
85 #ifdef PV_USE_OPENMP_THREADS
86 #pragma omp parallel for reduction(+ : sum)
87 #endif // PV_USE_OPENMP_THREADS
88  for (int k = 0; k < getTargetLayer()->getNumNeurons(); k++) {
89  int kex = kIndexExtended(k, nx, ny, nf, lt, rt, dn, up);
90  int kexMask = kIndexExtended(k, nx, ny, nf, maskLt, maskRt, maskDn, maskUp);
91  if (maskLayerData[kexMask]) {
92  float val = fabsf(aBuffer[kex]);
93  sum += val > nnzThreshold;
94  }
95  }
96  }
97  }
98  else {
99  if (getTargetLayer()->getSparseFlag()) {
100  PVLayerCube cube = getTargetLayer()->getPublisher()->createCube();
101  long int numActive = cube.numActive[index];
102  int numItems = cube.numItems / cube.loc.nbatch;
103  SparseList<float>::Entry const *activeList =
104  &((SparseList<float>::Entry *)cube.activeIndices)[index * numItems];
105 #ifdef PV_USE_OPENMP_THREADS
106 #pragma omp parallel for reduction(+ : sum)
107 #endif // PV_USE_OPENMP_THREADS
108  for (int k = 0; k < numActive; k++) {
109  int extIndex = activeList[k].index;
110  int inRestricted = !extendedIndexInBorderRegion(
111  extIndex, nx, ny, nf, halo->lt, halo->rt, halo->dn, halo->up);
112  float val = inRestricted * fabsf(aBuffer[extIndex]);
113  sum += val > nnzThreshold;
114  }
115  }
116  else {
117 #ifdef PV_USE_OPENMP_THREADS
118 #pragma omp parallel for reduction(+ : sum)
119 #endif // PV_USE_OPENMP_THREADS
120  for (int k = 0; k < getTargetLayer()->getNumNeurons(); k++) {
121  int kex = kIndexExtended(k, nx, ny, nf, lt, rt, dn, up);
122  float val = fabsf(aBuffer[kex]);
123  sum += val > nnzThreshold;
124  }
125  }
126  }
127 
128  return (double)sum;
129 }
130 
132 
133 } // end namespace PV
virtual int setNormDescription() override
PVLayerCube createCube(int delay=0)
Definition: Publisher.cpp:60
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
int setNormDescriptionToString(char const *s)
virtual void ioParam_nnzThreshold(enum ParamsIOFlag ioFlag)
nnzThreshold: The threshold for computing the L0-norm. getValue(t, index) returns the number of targe...
Definition: L0NormProbe.cpp:33
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: L0NormProbe.cpp:27
virtual double getValueInternal(double timevalue, int index) override
Definition: L0NormProbe.cpp:37
const float * getLayerData(int delay=0)