PetaVision  Alpha
CloneVLayer.cpp
1 /*
2  * CloneVLayer.cpp
3  *
4  * Created on: Aug 15, 2013
5  * Author: pschultz
6  */
7 
8 #include "CloneVLayer.hpp"
9 
10 namespace PV {
11 
12 CloneVLayer::CloneVLayer(const char *name, HyPerCol *hc) {
13  initialize_base();
14  initialize(name, hc);
15 }
16 
17 CloneVLayer::CloneVLayer() {
18  initialize_base();
19  // initialize() gets called by subclass's initialize method
20 }
21 
22 int CloneVLayer::initialize_base() {
23  numChannels = 0;
24  originalLayerName = NULL;
25  originalLayer = NULL;
26  return PV_SUCCESS;
27 }
28 
29 int CloneVLayer::initialize(const char *name, HyPerCol *hc) {
30  int status = HyPerLayer::initialize(name, hc);
31  return status;
32 }
33 
34 int CloneVLayer::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
35  int status = HyPerLayer::ioParamsFillGroup(ioFlag);
36  ioParam_originalLayerName(ioFlag);
37  return status;
38 }
39 
40 void CloneVLayer::ioParam_originalLayerName(enum ParamsIOFlag ioFlag) {
41  parent->parameters()->ioParamStringRequired(
42  ioFlag, name, "originalLayerName", &originalLayerName);
43 }
44 
45 void CloneVLayer::ioParam_InitVType(enum ParamsIOFlag ioFlag) {
46  if (ioFlag == PARAMS_IO_READ) {
47  parent->parameters()->handleUnnecessaryParameter(name, "InitVType");
48  }
49 }
50 
51 Response::Status
52 CloneVLayer::communicateInitInfo(std::shared_ptr<CommunicateInitInfoMessage const> message) {
53  auto status = HyPerLayer::communicateInitInfo(message);
54  if (!Response::completed(status)) {
55  return status;
56  }
57  originalLayer = message->lookup<HyPerLayer>(std::string(originalLayerName));
58  if (originalLayer == NULL) {
59  if (parent->columnId() == 0) {
60  ErrorLog().printf(
61  "%s: originalLayerName \"%s\" is not a layer in the HyPerCol.\n",
62  getDescription_c(),
63  originalLayerName);
64  }
65  MPI_Barrier(parent->getCommunicator()->communicator());
66  exit(EXIT_FAILURE);
67  }
68  const PVLayerLoc *srcLoc = originalLayer->getLayerLoc();
69  const PVLayerLoc *loc = getLayerLoc();
70  assert(srcLoc != NULL && loc != NULL);
71  if (srcLoc->nxGlobal != loc->nxGlobal || srcLoc->nyGlobal != loc->nyGlobal
72  || srcLoc->nf != loc->nf) {
73  if (parent->columnId() == 0) {
74  ErrorLog(errorMessage);
75  errorMessage.printf(
76  "%s: originalLayerName \"%s\" does not have the same dimensions.\n",
77  getDescription_c(),
78  originalLayerName);
79  errorMessage.printf(
80  " original (nx=%d, ny=%d, nf=%d) versus (nx=%d, ny=%d, nf=%d)\n",
81  srcLoc->nxGlobal,
82  srcLoc->nyGlobal,
83  srcLoc->nf,
84  loc->nxGlobal,
85  loc->nyGlobal,
86  loc->nf);
87  }
88  MPI_Barrier(parent->getCommunicator()->communicator());
89  exit(EXIT_FAILURE);
90  }
91  assert(srcLoc->nx == loc->nx && srcLoc->ny == loc->ny);
92  return Response::SUCCESS;
93 }
94 
95 int CloneVLayer::requireMarginWidth(int marginWidthNeeded, int *marginWidthResult, char axis) {
96  HyPerLayer::requireMarginWidth(marginWidthNeeded, marginWidthResult, axis);
97  assert(*marginWidthResult >= marginWidthNeeded);
98  return PV_SUCCESS;
99 }
100 
101 Response::Status CloneVLayer::allocateDataStructures() {
102  assert(originalLayer);
103  auto status = Response::SUCCESS;
104  // Make sure originalLayer has allocated its V buffer before copying its address to clone's V
105  // buffer
106  if (originalLayer->getDataStructuresAllocatedFlag()) {
107  status = HyPerLayer::allocateDataStructures();
108  }
109  else {
110  status = Response::POSTPONE;
111  }
112  return status;
113 }
114 
115 void CloneVLayer::allocateV() {
116  assert(originalLayer && originalLayer->getCLayer());
117  clayer->V = originalLayer->getV();
118  if (getV() == NULL) {
119  Fatal().printf(
120  "%s: originalLayer \"%s\" has a null V buffer in rank %d process.\n",
121  getDescription_c(),
122  originalLayerName,
123  parent->columnId());
124  }
125 }
126 
127 int CloneVLayer::requireChannel(int channelNeeded, int *numChannelsResult) {
128  if (parent->columnId() == 0) {
129  ErrorLog().printf(
130  "%s: layers derived from CloneVLayer do not have GSyn channels (requireChannel called "
131  "with channel %d)\n",
132  getDescription_c(),
133  channelNeeded);
134  }
135  return PV_FAILURE;
136 }
137 
138 void CloneVLayer::allocateGSyn() { pvAssert(GSyn == nullptr); }
139 
140 void CloneVLayer::initializeV() {}
141 
142 void CloneVLayer::readVFromCheckpoint(Checkpointer *checkpointer) {
143  // If we just inherit HyPerLayer::readVFromCheckpoint, we checkpoint V since it is non-null.
144  // This is redundant since V is a clone.
145 }
146 
147 Response::Status CloneVLayer::registerData(Checkpointer *checkpointer) {
148  float *V = clayer->V;
149  clayer->V = nullptr;
150  auto status = HyPerLayer::registerData(checkpointer);
151  clayer->V = V;
152  return status;
153 }
154 
155 Response::Status CloneVLayer::updateState(double timed, double dt) {
156  const PVLayerLoc *loc = getLayerLoc();
157  float *A = clayer->activity->data;
158  float *V = getV();
159  int num_channels = getNumChannels();
160  float *gSynHead = GSyn == NULL ? NULL : GSyn[0];
161  int nx = loc->nx;
162  int ny = loc->ny;
163  int nf = loc->nf;
164  int num_neurons = nx * ny * nf;
165  int nbatch = loc->nbatch;
166  setActivity_HyPerLayer(
167  nbatch,
168  num_neurons,
169  A,
170  V,
171  nx,
172  ny,
173  loc->nf,
174  loc->halo.lt,
175  loc->halo.rt,
176  loc->halo.dn,
177  loc->halo.up);
178  return Response::SUCCESS;
179 }
180 
181 CloneVLayer::~CloneVLayer() {
182  free(originalLayerName);
183  clayer->V = NULL;
184 }
185 
186 } /* namespace PV */
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: HyPerLayer.cpp:571
virtual void ioParam_InitVType(enum ParamsIOFlag ioFlag) override
initVType: Specifies how to initialize the V buffer.
Definition: CloneVLayer.cpp:45
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: CloneVLayer.cpp:34
bool getDataStructuresAllocatedFlag() const
Definition: BaseObject.hpp:102
static bool completed(Status &a)
Definition: Response.hpp:49
int initialize(const char *name, HyPerCol *hc)
Definition: HyPerLayer.cpp:129