PetaVision  Alpha
BackgroundLayer.cpp
1 /*
2  * BackgroundLayer.cpp
3  *
4  * Created on: 4/16/15
5  * slundquist
6  */
7 
8 #include "BackgroundLayer.hpp"
9 #include <stdio.h>
10 
11 #include "../include/default_params.h"
12 
13 namespace PV {
14 BackgroundLayer::BackgroundLayer() { initialize_base(); }
15 
16 BackgroundLayer::BackgroundLayer(const char *name, HyPerCol *hc) {
17  initialize_base();
18  initialize(name, hc);
19 }
20 
21 BackgroundLayer::~BackgroundLayer() {}
22 
23 int BackgroundLayer::initialize_base() {
24  originalLayer = NULL;
25  repFeatureNum = 1;
26  return PV_SUCCESS;
27 }
28 
29 int BackgroundLayer::initialize(const char *name, HyPerCol *hc) {
30  int status_init = CloneVLayer::initialize(name, hc);
31 
32  return status_init;
33 }
34 
35 Response::Status
36 BackgroundLayer::communicateInitInfo(std::shared_ptr<CommunicateInitInfoMessage const> message) {
37  auto status = HyPerLayer::communicateInitInfo(message);
38  if (!Response::completed(status)) {
39  return status;
40  }
41  originalLayer = message->lookup<HyPerLayer>(std::string(originalLayerName));
42  if (originalLayer == NULL) {
43  if (parent->getCommunicator()->globalCommRank() == 0) {
44  ErrorLog().printf(
45  "%s: originalLayerName \"%s\" is not a layer in the HyPerCol.\n",
46  getDescription_c(),
47  originalLayerName);
48  }
49  MPI_Barrier(parent->getCommunicator()->globalCommunicator());
50  exit(EXIT_FAILURE);
51  }
52  const PVLayerLoc *srcLoc = originalLayer->getLayerLoc();
53  const PVLayerLoc *loc = getLayerLoc();
54  assert(srcLoc != NULL && loc != NULL);
55  if (srcLoc->nxGlobal != loc->nxGlobal || srcLoc->nyGlobal != loc->nyGlobal) {
56  if (parent->columnId() == 0) {
57  ErrorLog(errorMessage);
58  errorMessage.printf(
59  "%s: originalLayerName \"%s\" does not have the same X/Y dimensions.\n",
60  getDescription_c(),
61  originalLayerName);
62  errorMessage.printf(
63  " original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
64  srcLoc->nxGlobal,
65  srcLoc->nyGlobal,
66  srcLoc->nf,
67  loc->nxGlobal,
68  loc->nyGlobal,
69  loc->nf);
70  }
71  MPI_Barrier(parent->getCommunicator()->communicator());
72  exit(EXIT_FAILURE);
73  }
74  if ((srcLoc->nf + 1) * repFeatureNum != loc->nf) {
75  if (parent->columnId() == 0) {
76  ErrorLog(errorMessage);
77  errorMessage.printf(
78  "%s: nf must have (n+1)*repFeatureNum (%d) features in BackgroundLayer \"%s\", "
79  "where n is the orig layer number of features.\n",
80  getDescription_c(),
81  (srcLoc->nf + 1) * repFeatureNum,
82  originalLayerName);
83  errorMessage.printf(
84  " original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
85  srcLoc->nxGlobal,
86  srcLoc->nyGlobal,
87  srcLoc->nf,
88  loc->nxGlobal,
89  loc->nyGlobal,
90  loc->nf);
91  }
92  MPI_Barrier(parent->getCommunicator()->communicator());
93  exit(EXIT_FAILURE);
94  }
95  assert(srcLoc->nx == loc->nx && srcLoc->ny == loc->ny);
96  return Response::SUCCESS;
97 }
98 
99 // Background Layer does not use the V buffer, so absolutely fine to clone off of an null V layer
100 void BackgroundLayer::allocateV() {
101  // Do nothing
102 }
103 
104 void BackgroundLayer::ioParam_repFeatureNum(enum ParamsIOFlag ioFlag) {
105  parent->parameters()->ioParamValue(ioFlag, name, "repFeatureNum", &repFeatureNum, repFeatureNum);
106  if (repFeatureNum <= 0) {
107  Fatal() << "BackgroundLayer " << name << ": repFeatureNum must an integer greater or equal "
108  "to 1 (1 feature means no replication)\n";
109  }
110 }
111 
112 int BackgroundLayer::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
114  ioParam_repFeatureNum(ioFlag);
115  return PV_SUCCESS;
116 }
117 
118 int BackgroundLayer::setActivity() {
119  float *activity = clayer->activity->data;
120  memset(activity, 0, sizeof(float) * clayer->numExtendedAllBatches);
121  return 0;
122 }
123 
124 Response::Status BackgroundLayer::updateState(double timef, double dt) {
125  float *A = clayer->activity->data;
126  const float *originalA = originalLayer->getCLayer()->activity->data;
127  const PVLayerLoc *loc = getLayerLoc();
128  const PVLayerLoc *locOriginal = originalLayer->getLayerLoc();
129 
130  // Make sure all sizes match
131  assert(locOriginal->nx == loc->nx);
132  assert(locOriginal->ny == loc->ny);
133  assert((locOriginal->nf + 1) * repFeatureNum == loc->nf);
134 
135  int nx = loc->nx;
136  int ny = loc->ny;
137  int origNf = locOriginal->nf;
138  int thisNf = loc->nf;
139  int nbatch = loc->nbatch;
140 
141  PVHalo const *halo = &loc->halo;
142  PVHalo const *haloOrig = &locOriginal->halo;
143 
144  for (int b = 0; b < nbatch; b++) {
145  float *ABatch = A + b * getNumExtended();
146  const float *originalABatch = originalA + b * originalLayer->getNumExtended();
147 
148 // Loop through all nx and ny
149 // each y value specifies a different target so ok to thread here (sum, sumsq are defined inside
150 // loop)
151 #ifdef PV_USE_OPENMP_THREADS
152 #pragma omp parallel for
153 #endif
154  for (int iY = 0; iY < ny; iY++) {
155  for (int iX = 0; iX < nx; iX++) {
156  // outVal stores the NOR of the other values
157  int outVal = 1;
158  // Shift all features down by one
159  for (int iF = 0; iF < origNf; iF++) {
160  int kextOrig = kIndex(
161  iX,
162  iY,
163  iF,
164  nx + haloOrig->lt + haloOrig->rt,
165  ny + haloOrig->dn + haloOrig->up,
166  origNf);
167  float origActivity = originalABatch[kextOrig];
168  // outVal is the final out value for the background
169  if (origActivity != 0) {
170  outVal = 0;
171  }
172  // Loop over replicated features
173  for (int repIdx = 0; repIdx < repFeatureNum; repIdx++) {
174  // Index iF one down, multiply by replicate feature number, add repIdx offset
175  int newFeatureIdx = ((iF + 1) * repFeatureNum) + repIdx;
176  assert(newFeatureIdx < thisNf);
177  int kext = kIndex(
178  iX,
179  iY,
180  newFeatureIdx,
181  nx + halo->lt + halo->rt,
182  ny + halo->dn + halo->up,
183  thisNf);
184  ABatch[kext] = origActivity;
185  }
186  }
187  // Set background indices to outVal
188  for (int repIdx = 0; repIdx < repFeatureNum; repIdx++) {
189  int kextBackground = kIndex(
190  iX, iY, repIdx, nx + halo->lt + halo->rt, ny + halo->dn + halo->up, thisNf);
191  ABatch[kextBackground] = outVal;
192  }
193  }
194  }
195  }
196  return Response::SUCCESS;
197 }
198 
199 } // end namespace PV
int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: CloneVLayer.cpp:34
static bool completed(Status &a)
Definition: Response.hpp:49