PetaVision  Alpha
InputRegionLayer.cpp
1 /*
2  * InputRegionLayer.cpp
3  *
4  * Created on: Aug 30, 2017
5  * Author: pschultz
6  */
7 
8 #include "InputRegionLayer.hpp"
9 
10 namespace PV {
11 
12 InputRegionLayer::InputRegionLayer(const char *name, HyPerCol *hc) {
13  initialize_base();
14  initialize(name, hc);
15 }
16 
17 InputRegionLayer::InputRegionLayer() {
18  initialize_base();
19  // initialize() gets called by subclass's initialize method
20 }
21 
22 int InputRegionLayer::initialize_base() {
23  numChannels = 0;
24  originalLayerName = nullptr;
25  originalLayer = nullptr;
26  return PV_SUCCESS;
27 }
28 
29 int InputRegionLayer::initialize(const char *name, HyPerCol *hc) {
30  int status = HyPerLayer::initialize(name, hc);
31  return status;
32 }
33 
34 int InputRegionLayer::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
35  int status = HyPerLayer::ioParamsFillGroup(ioFlag);
36  ioParam_originalLayerName(ioFlag);
37  return status;
38 }
39 
40 void InputRegionLayer::ioParam_originalLayerName(enum ParamsIOFlag ioFlag) {
41  parent->parameters()->ioParamStringRequired(
42  ioFlag, name, "originalLayerName", &originalLayerName);
43 }
44 
45 void InputRegionLayer::ioParam_phase(enum ParamsIOFlag ioFlag) {
46  if (ioFlag == PARAMS_IO_READ) {
47  // Phase will be copied from original layer in CommunicateInitInfo stage,
48  // but probably is not needed.
49  parent->parameters()->handleUnnecessaryParameter(name, "phase");
50  }
51 }
52 
53 void InputRegionLayer::ioParam_mirrorBCflag(enum ParamsIOFlag ioFlag) {
54  if (ioFlag == PARAMS_IO_READ) {
55  // mirrorBCflag will be copied from original layer in CommunicateInitInfo stage.
56  parent->parameters()->handleUnnecessaryParameter(name, "mirrorBCflag");
57  }
58 }
59 
60 void InputRegionLayer::ioParam_valueBC(enum ParamsIOFlag ioFlag) {
61  if (ioFlag == PARAMS_IO_READ) {
62  // mirrorBCflag will be copied from original layer in CommunicateInitInfo stage.
63  parent->parameters()->handleUnnecessaryParameter(name, "valueBC");
64  }
65 }
66 
67 void InputRegionLayer::ioParam_InitVType(enum ParamsIOFlag ioFlag) {
68  if (ioFlag == PARAMS_IO_READ) {
69  initVTypeString = nullptr;
70  parent->parameters()->handleUnnecessaryParameter(name, "InitVType");
71  }
72 }
73 
74 void InputRegionLayer::ioParam_triggerLayerName(enum ParamsIOFlag ioFlag) {
75  if (ioFlag == PARAMS_IO_READ) {
76  triggerLayerName = nullptr;
77  triggerFlag = false;
78  parent->parameters()->handleUnnecessaryParameter(name, "triggerLayerName");
79  }
80 }
81 
82 void InputRegionLayer::ioParam_sparseLayer(enum ParamsIOFlag ioFlag) {
83  if (ioFlag == PARAMS_IO_READ) {
84  sparseLayer = false;
85  parent->parameters()->handleUnnecessaryParameter(name, "sparseLayer");
86  }
87 }
88 
89 void InputRegionLayer::ioParam_updateGpu(enum ParamsIOFlag ioFlag) {
90 #ifdef PV_USE_CUDA
91  if (ioFlag == PARAMS_IO_READ) {
92  mUpdateGpu = false;
93  parent->parameters()->handleUnnecessaryParameter(name, "updateGpu");
94  }
95 #endif // PV_USE_CUDA
96 }
97 
98 Response::Status
99 InputRegionLayer::communicateInitInfo(std::shared_ptr<CommunicateInitInfoMessage const> message) {
100  auto status = HyPerLayer::communicateInitInfo(message);
101  if (!Response::completed(status)) {
102  return status;
103  }
104  setOriginalLayer(message->lookup<HyPerLayer>(std::string(originalLayerName)));
105  pvAssert(originalLayer);
106  if (!originalLayer->getInitInfoCommunicatedFlag()) {
107  return Response::POSTPONE; // Make sure original layer has all the information we need to copy
108  }
109  phase = originalLayer->getPhase();
110  mirrorBCflag = originalLayer->useMirrorBCs();
111  valueBC = originalLayer->getValueBC();
112  checkLayerDimensions();
113  synchronizeMarginWidth(originalLayer);
114  originalLayer->synchronizeMarginWidth(this);
115  return Response::SUCCESS;
116 }
117 
118 void InputRegionLayer::setOriginalLayer(HyPerLayer *layer) {
119  if (layer == nullptr) {
120  if (parent->columnId() == 0) {
121  ErrorLog().printf(
122  "%s: originalLayerName \"%s\" is not a layer in the HyPerCol.\n",
123  getDescription_c(),
124  originalLayerName);
125  }
126  MPI_Barrier(parent->getCommunicator()->communicator());
127  exit(EXIT_FAILURE);
128  }
129  originalLayer = dynamic_cast<InputLayer *>(layer);
130  if (originalLayer == nullptr) {
131  if (parent->columnId() == 0) {
132  ErrorLog().printf(
133  "%s: originalLayerName \"%s\" is not an InputLayer-derived class.\n",
134  getDescription_c(),
135  originalLayerName);
136  }
137  MPI_Barrier(parent->getCommunicator()->communicator());
138  exit(EXIT_FAILURE);
139  }
140  originalLayer->makeInputRegionsPointer();
141 }
142 
143 void InputRegionLayer::checkLayerDimensions() {
144  pvAssert(originalLayer);
145  const PVLayerLoc *srcLoc = originalLayer->getLayerLoc();
146  const PVLayerLoc *loc = getLayerLoc();
147  pvAssert(srcLoc != nullptr && loc != nullptr);
148  if (srcLoc->nxGlobal != loc->nxGlobal || srcLoc->nyGlobal != loc->nyGlobal
149  || srcLoc->nf != loc->nf) {
150  if (parent->columnId() == 0) {
151  ErrorLog(errorMessage);
152  errorMessage.printf(
153  "%s: originalLayerName \"%s\" does not have the same dimensions.\n",
154  getDescription_c(),
155  originalLayerName);
156  errorMessage.printf(
157  " original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
158  srcLoc->nxGlobal,
159  srcLoc->nyGlobal,
160  srcLoc->nf,
161  loc->nxGlobal,
162  loc->nyGlobal,
163  loc->nf);
164  }
165  MPI_Barrier(parent->getCommunicator()->communicator());
166  exit(EXIT_FAILURE);
167  }
168  pvAssert(srcLoc->nx == loc->nx && srcLoc->ny == loc->ny);
169 }
170 
171 Response::Status InputRegionLayer::allocateDataStructures() {
172  if (!originalLayer->getDataStructuresAllocatedFlag()) {
173  // original layer needs to create InputRegionsAllBatchElements first
174  return Response::POSTPONE;
175  }
176  return HyPerLayer::allocateDataStructures();
177 }
178 
179 void InputRegionLayer::allocateV() { clayer->V = nullptr; }
180 
181 void InputRegionLayer::allocateActivity() {
182  int const numItems = getNumExtendedAllBatches();
183  PVLayerCube *cube = (PVLayerCube *)calloc(pvcube_size(numItems), sizeof(char));
184  FatalIf(cube == nullptr, "Unable to allocate PVLayerCube for %s\n", getDescription_c());
185  cube->size = pvcube_size(numItems);
186  cube->numItems = numItems;
187  cube->loc = *getLayerLoc();
188  cube->data = originalLayer->getInputRegionsAllBatchElements();
189  clayer->activity = cube;
190 }
191 
192 int InputRegionLayer::setActivity() { return PV_SUCCESS; }
193 
194 int InputRegionLayer::requireChannel(int channelNeeded, int *numChannelsResult) {
195  if (parent->columnId() == 0) {
196  ErrorLog().printf(
197  "%s: layers derived from InputRegionLayer do not have GSyn channels (requireChannel "
198  "called "
199  "with channel %d)\n",
200  getDescription_c(),
201  channelNeeded);
202  }
203  return PV_FAILURE;
204 }
205 
206 void InputRegionLayer::allocateGSyn() { pvAssert(GSyn == nullptr); }
207 
208 bool InputRegionLayer::needUpdate(double timed, double dt) { return false; }
209 
210 InputRegionLayer::~InputRegionLayer() { free(originalLayerName); }
211 
212 } /* namespace PV */
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: HyPerLayer.cpp:571
virtual void ioParam_sparseLayer(enum ParamsIOFlag ioFlag) override
sparseLayer: Specifies if the layer should be considered sparese for optimization and output ...
bool getDataStructuresAllocatedFlag() const
Definition: BaseObject.hpp:102
virtual void ioParam_updateGpu(enum ParamsIOFlag ioFlag) override
updateGpu: When compiled using CUDA or OpenCL GPU acceleration, this flag tells whether this layer&#39;s ...
static bool completed(Status &a)
Definition: Response.hpp:49
int initialize(const char *name, HyPerCol *hc)
Definition: HyPerLayer.cpp:129
virtual void ioParam_InitVType(enum ParamsIOFlag ioFlag) override
initVType: Specifies how to initialize the V buffer.
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
virtual bool needUpdate(double timestamp, double dt) override
virtual void ioParam_mirrorBCflag(enum ParamsIOFlag ioFlag) override
mirrorBCflag: If set to true, the margin will mirror the data
virtual void ioParam_phase(enum ParamsIOFlag ioFlag) override
phase: Defines the ordering in which each layer is updated
virtual void ioParam_triggerLayerName(enum ParamsIOFlag ioFlag) override
triggerLayerName: Specifies the name of the layer that this layer triggers off of. If set to NULL or the empty string, the layer does not trigger but updates its state on every timestep.
virtual void ioParam_valueBC(enum ParamsIOFlag ioFlag) override
valueBC: If mirrorBC is set to true, Uses the specified value for the margin area ...
bool getInitInfoCommunicatedFlag() const
Definition: BaseObject.hpp:95