PetaVision  Alpha
ANNErrorLayer.cpp
1 /*
2  * ANNErrorLayer.cpp
3  *
4  * Created on: Jun 21, 2013
5  * Author: gkenyon
6  */
7 
8 #include "ANNErrorLayer.hpp"
9 
10 void ANNErrorLayer_update_state(
11  const int nbatch,
12  const int numNeurons,
13  const int nx,
14  const int ny,
15  const int nf,
16  const int lt,
17  const int rt,
18  const int dn,
19  const int up,
20 
21  float *V,
22  int numVertices,
23  float *verticesV,
24  float *verticesA,
25  float *slopes,
26  float *GSynHead,
27  float *activity,
28  const float errScale);
29 
30 namespace PV {
31 
32 ANNErrorLayer::ANNErrorLayer() { initialize_base(); }
33 
34 ANNErrorLayer::ANNErrorLayer(const char *name, HyPerCol *hc) {
35  int status = initialize_base();
36  if (status == PV_SUCCESS) {
37  status = initialize(name, hc);
38  }
39  if (status != PV_SUCCESS) {
40  Fatal().printf("Creating ANNErrorLayer \"%s\" failed.\n", name);
41  }
42 }
43 
44 ANNErrorLayer::~ANNErrorLayer() {}
45 
46 int ANNErrorLayer::initialize_base() {
47  errScale = 1;
48  return PV_SUCCESS;
49 }
50 
51 int ANNErrorLayer::initialize(const char *name, HyPerCol *hc) {
52  int status = ANNLayer::initialize(name, hc);
53  return status;
54 }
55 
56 int ANNErrorLayer::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
57  int status = ANNLayer::ioParamsFillGroup(ioFlag);
58  ioParam_errScale(ioFlag);
59  return status;
60 }
61 
62 void ANNErrorLayer::ioParam_errScale(enum ParamsIOFlag ioFlag) {
63  parent->parameters()->ioParamValue(
64  ioFlag, name, "errScale", &errScale, errScale, true /*warnIfAbsent*/);
65 }
66 
68  pvAssert(!layerListsVerticesInParams());
69  slopeNegInf = 1.0;
70  slopePosInf = 1.0;
71  if (VThresh > 0) {
72  numVertices = 4;
73  verticesV = (float *)malloc((size_t)numVertices * sizeof(*verticesV));
74  verticesA = (float *)malloc((size_t)numVertices * sizeof(*verticesA));
75  if (verticesV == NULL || verticesA == NULL) {
76  Fatal().printf(
77  "%s: unable to allocate memory for vertices: %s\n",
78  getDescription_c(),
79  strerror(errno));
80  }
81  verticesV[0] = -VThresh;
82  verticesA[0] = -VThresh;
83  verticesV[1] = -VThresh;
84  verticesA[1] = 0.0;
85  verticesV[2] = VThresh;
86  verticesA[2] = 0.0;
87  verticesV[3] = VThresh;
88  verticesA[3] = VThresh;
89  }
90  else {
91  // checkVertices will complain if VThresh is negative but not "negative infinity"
92  numVertices = 1;
93  verticesV = (float *)malloc((size_t)numVertices * sizeof(*verticesV));
94  verticesA = (float *)malloc((size_t)numVertices * sizeof(*verticesA));
95  if (verticesV == NULL || verticesA == NULL) {
96  Fatal().printf(
97  "%s: unable to allocate memory for vertices: %s\n",
98  getDescription_c(),
99  strerror(errno));
100  }
101  verticesV[0] = 0.0f;
102  verticesA[0] = 0.0f;
103  }
104  return PV_SUCCESS;
105 }
106 
108  int status = PV_SUCCESS;
109  if (VThresh < 0 && VThresh > -(float)0.999 * FLT_MAX) { // 0.999 is to allow for imprecision from
110  // params files using 3.40282e+38 instead
111  // of infinity
112  if (parent->columnId() == 0) {
113  ErrorLog().printf(
114  "%s: VThresh cannot be negative (value is %f).\n",
115  getDescription_c(),
116  (double)VThresh);
117  }
118  status = PV_FAILURE;
119  }
120  else {
121  pvAssert(ANNLayer::checkVertices() == PV_SUCCESS);
122  }
123  return status;
124 }
125 
126 Response::Status ANNErrorLayer::updateState(double time, double dt) {
127  const PVLayerLoc *loc = getLayerLoc();
128  float *A = clayer->activity->data;
129  float *V = getV();
130  int num_channels = getNumChannels();
131  float *gSynHead = GSyn == NULL ? NULL : GSyn[0];
132  int nx = loc->nx;
133  int ny = loc->ny;
134  int nf = loc->nf;
135  int num_neurons = nx * ny * nf;
136  int nbatch = loc->nbatch;
137  ANNErrorLayer_update_state(
138  nbatch,
139  num_neurons,
140  nx,
141  ny,
142  nf,
143  loc->halo.lt,
144  loc->halo.rt,
145  loc->halo.dn,
146  loc->halo.up,
147  V,
148  numVertices,
149  verticesV,
150  verticesA,
151  slopes,
152  gSynHead,
153  A,
154  errScale);
155  return Response::SUCCESS;
156 }
157 
158 } /* namespace PV */
159 
160 void ANNErrorLayer_update_state(
161  const int nbatch,
162  const int numNeurons,
163  const int nx,
164  const int ny,
165  const int nf,
166  const int lt,
167  const int rt,
168  const int dn,
169  const int up,
170 
171  float *V,
172  int numVertices,
173  float *verticesV,
174  float *verticesA,
175  float *slopes,
176  float *GSynHead,
177  float *activity,
178  const float errScale) {
179  updateV_ANNErrorLayer(
180  nbatch,
181  numNeurons,
182  V,
183  GSynHead,
184  activity,
185  numVertices,
186  verticesV,
187  verticesA,
188  slopes,
189  nx,
190  ny,
191  nf,
192  lt,
193  rt,
194  dn,
195  up,
196  errScale);
197 }
bool layerListsVerticesInParams() const
Definition: ANNLayer.hpp:30
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
virtual int checkVertices() const override
virtual void ioParam_errScale(enum ParamsIOFlag ioFlag)
: errScale: The input to the error layer is multiplied by errScale before applying the threshold...
virtual int checkVertices() const
Definition: ANNLayer.cpp:386
virtual int setVertices() override
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: ANNLayer.cpp:89