PetaVision  Alpha
PointProbe.cpp
1 /*
2  * PointProbe.cpp
3  *
4  * Created on: Mar 10, 2009
5  * Author: Craig Rasmussen
6  */
7 
8 #include "PointProbe.hpp"
9 #include "../layers/HyPerLayer.hpp"
10 #include <string.h>
11 
12 namespace PV {
13 
14 PointProbe::PointProbe() {
15  initialize_base();
16  // Default constructor for derived classes. Derived classes should call
17  // PointProbe::initialize from their init-method.
18 }
19 
20 PointProbe::PointProbe(const char *name, HyPerCol *hc) : LayerProbe() {
21  initialize_base();
22  initialize(name, hc);
23 }
24 
25 PointProbe::~PointProbe() {}
26 
27 int PointProbe::initialize_base() {
28  xLoc = 0;
29  yLoc = 0;
30  fLoc = 0;
31  batchLoc = 0;
32  return PV_SUCCESS;
33 }
34 
35 int PointProbe::initialize(const char *name, HyPerCol *hc) {
36  int status = LayerProbe::initialize(name, hc);
37  return status;
38 }
39 
40 int PointProbe::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
41  int status = LayerProbe::ioParamsFillGroup(ioFlag);
42  ioParam_xLoc(ioFlag);
43  ioParam_yLoc(ioFlag);
44  ioParam_fLoc(ioFlag);
45  ioParam_batchLoc(ioFlag);
46  return status;
47 }
48 
49 void PointProbe::ioParam_xLoc(enum ParamsIOFlag ioFlag) {
50  parent->parameters()->ioParamValueRequired(ioFlag, getName(), "xLoc", &xLoc);
51 }
52 
53 void PointProbe::ioParam_yLoc(enum ParamsIOFlag ioFlag) {
54  parent->parameters()->ioParamValueRequired(ioFlag, getName(), "yLoc", &yLoc);
55 }
56 
57 void PointProbe::ioParam_fLoc(enum ParamsIOFlag ioFlag) {
58  parent->parameters()->ioParamValueRequired(ioFlag, getName(), "fLoc", &fLoc);
59 }
60 
61 void PointProbe::ioParam_batchLoc(enum ParamsIOFlag ioFlag) {
62  parent->parameters()->ioParamValueRequired(ioFlag, getName(), "batchLoc", &batchLoc);
63 }
64 
66 
67 Response::Status
68 PointProbe::communicateInitInfo(std::shared_ptr<CommunicateInitInfoMessage const> message) {
69  auto status = LayerProbe::communicateInitInfo(message);
70  if (!Response::completed(status)) {
71  return status;
72  }
73  assert(getTargetLayer());
74  const PVLayerLoc *loc = getTargetLayer()->getLayerLoc();
75  bool isRoot = parent->getCommunicator()->commRank() == 0;
76  bool failed = false;
77  if ((xLoc < 0 || xLoc > loc->nxGlobal) && isRoot) {
78  ErrorLog().printf(
79  "PointProbe on layer %s: xLoc coordinate %d is out "
80  "of bounds (layer has %d neurons in "
81  "the x-direction.\n",
82  getTargetLayer()->getName(),
83  xLoc,
84  loc->nxGlobal);
85  failed = true;
86  }
87  if ((yLoc < 0 || yLoc > loc->nyGlobal) && isRoot) {
88  ErrorLog().printf(
89  "PointProbe on layer %s: yLoc coordinate %d is out "
90  "of bounds (layer has %d neurons in "
91  "the y-direction.\n",
92  getTargetLayer()->getName(),
93  yLoc,
94  loc->nyGlobal);
95  failed = true;
96  }
97  if ((fLoc < 0 || fLoc > loc->nf) && isRoot) {
98  ErrorLog().printf(
99  "PointProbe on layer %s: fLoc coordinate %d is out "
100  "of bounds (layer has %d features.\n",
101  getTargetLayer()->getName(),
102  fLoc,
103  loc->nf);
104  failed = true;
105  }
106  if ((batchLoc < 0 || batchLoc > loc->nbatch) && isRoot) {
107  ErrorLog().printf(
108  "PointProbe on layer %s: batchLoc coordinate %d is "
109  "out of bounds (layer has %d "
110  "batches.\n",
111  getTargetLayer()->getName(),
112  batchLoc,
113  loc->nbatch);
114  failed = true;
115  }
116  if (failed)
117  exit(EXIT_FAILURE);
118  return Response::SUCCESS;
119 }
120 
121 void PointProbe::initOutputStreams(const char *filename, Checkpointer *checkpointer) {
122  PVLayerLoc const *loc = getTargetLayer()->getLayerLoc();
123  int xRank = xLoc / loc->nx; // integer division
124  int yRank = yLoc / loc->ny; // integer division
125  int batchRank = batchLoc / loc->nbatch; // integer division
126 
127  int blockColumnIndex = getMPIBlock()->getStartColumn() + getMPIBlock()->getColumnIndex();
128  int blockRowIndex = getMPIBlock()->getStartRow() + getMPIBlock()->getRowIndex();
129  int blockBatchIndex = getMPIBlock()->getStartBatch() + getMPIBlock()->getBatchIndex();
130 
131  if (xRank == blockColumnIndex and yRank == blockRowIndex and batchRank == blockBatchIndex) {
132  if (getProbeOutputFilename()) {
133  std::string path(getProbeOutputFilename());
134  std::ios_base::openmode mode = std::ios_base::out;
135  if (!checkpointer->getCheckpointReadDirectory().empty()) {
136  mode |= std::ios_base::app;
137  }
138  if (path[0] != '/') {
139  path = checkpointer->makeOutputPathFilename(path);
140  }
141  auto stream = new FileStream(path.c_str(), mode, checkpointer->doesVerifyWrites());
142  mOutputStreams.push_back(stream);
143  }
144  else {
145  auto stream = new PrintStream(PV::getOutputStream());
146  mOutputStreams.push_back(stream);
147  }
148  }
149  else {
150  mOutputStreams.clear();
151  }
152 }
153 
164 Response::Status PointProbe::outputState(double timef) {
165  getValues(timef);
166  writeState(timef);
167  return Response::SUCCESS;
168 }
169 
170 void PointProbe::calcValues(double timevalue) {
171  assert(this->getNumValues() == 2);
172  double *valuesBuffer = this->getValuesBuffer();
173  // We need to calculate which mpi process contains the target point, and send
174  // that info to the root process Each process calculates local index
175  const PVLayerLoc *loc = getTargetLayer()->getLayerLoc();
176  // Calculate local coords from global
177  const int kx0 = loc->kx0;
178  const int ky0 = loc->ky0;
179  const int kb0 = loc->kb0;
180  const int nx = loc->nx;
181  const int ny = loc->ny;
182  const int nf = loc->nf;
183  const int nbatch = loc->nbatch;
184  const int xLocLocal = xLoc - kx0;
185  const int yLocLocal = yLoc - ky0;
186  const int nbatchLocal = batchLoc - kb0;
187 
188  // if in bounds
189  if (xLocLocal >= 0 && xLocLocal < nx && yLocLocal >= 0 && yLocLocal < ny && nbatchLocal >= 0
190  && nbatchLocal < nbatch) {
191  const float *V = getTargetLayer()->getV();
192  const float *activity = getTargetLayer()->getLayerData();
193  // Send V and A to root
194  const int k = kIndex(xLocLocal, yLocLocal, fLoc, nx, ny, nf);
195  if (V) {
196  valuesBuffer[0] = V[k + nbatchLocal * getTargetLayer()->getNumNeurons()];
197  }
198  else {
199  valuesBuffer[0] = 0.0;
200  }
201  if (activity) {
202  const int kex = kIndexExtended(
203  k, nx, ny, nf, loc->halo.lt, loc->halo.rt, loc->halo.dn, loc->halo.up);
204  valuesBuffer[1] = activity[kex + nbatchLocal * getTargetLayer()->getNumExtended()];
205  }
206  else {
207  valuesBuffer[1] = 0.0;
208  }
209  // If not in root process, send to root process
210  if (parent->columnId() != 0) {
211  MPI_Send(valuesBuffer, 2, MPI_DOUBLE, 0, 0, parent->getCommunicator()->communicator());
212  }
213  }
214 
215  // Root process
216  if (parent->columnId() == 0) {
217  // Calculate which rank target neuron is
218  // TODO we need to calculate rank from batch as well
219  int xRank = xLoc / nx;
220  int yRank = yLoc / ny;
221 
222  int srcRank = rankFromRowAndColumn(
223  yRank,
224  xRank,
225  parent->getCommunicator()->numCommRows(),
226  parent->getCommunicator()->numCommColumns());
227 
228  // If srcRank is not root process, MPI_Recv from that rank
229  if (srcRank != 0) {
230  MPI_Recv(
231  valuesBuffer,
232  2,
233  MPI_DOUBLE,
234  srcRank,
235  0,
236  parent->getCommunicator()->communicator(),
237  MPI_STATUS_IGNORE);
238  }
239  }
240 }
241 
242 void PointProbe::writeState(double timevalue) {
243  if (!mOutputStreams.empty()) {
244  double *valuesBuffer = this->getValuesBuffer();
245  output(0).printf("%s t=%.1f V=%6.5f a=%.5f", getMessage(), timevalue, getV(), getA());
246  output(0) << std::endl;
247  }
248 }
249 
250 double PointProbe::getV() { return getValuesBuffer()[0]; }
251 
252 double PointProbe::getA() { return getValuesBuffer()[1]; }
253 
254 } // namespace PV
void setNumValues(int n)
Definition: BaseProbe.cpp:221
LayerProbe(const char *name, HyPerCol *hc)
Definition: LayerProbe.cpp:22
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: BaseProbe.cpp:76
char const * getProbeOutputFilename()
Definition: BaseProbe.hpp:314
PrintStream & output(int b)
Definition: BaseProbe.hpp:291
static bool completed(Status &a)
Definition: Response.hpp:49
virtual void initNumValues() override
Definition: PointProbe.cpp:65
int getStartColumn() const
Definition: MPIBlock.hpp:151
int getStartRow() const
Definition: MPIBlock.hpp:146
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: PointProbe.cpp:40
int getColumnIndex() const
Definition: MPIBlock.hpp:166
double * getValuesBuffer()
Definition: BaseProbe.hpp:319
virtual Response::Status communicateInitInfo(std::shared_ptr< CommunicateInitInfoMessage const > message) override
Definition: PointProbe.cpp:68
int initialize(const char *name, HyPerCol *hc)
Definition: LayerProbe.cpp:38
const char * getMessage()
Definition: BaseProbe.hpp:280
virtual Response::Status communicateInitInfo(std::shared_ptr< CommunicateInitInfoMessage const > message) override
Definition: LayerProbe.cpp:54
virtual void calcValues(double timevalue) override
Definition: PointProbe.cpp:170
void getValues(double timevalue, double *valuesVector)
Definition: BaseProbe.cpp:336
virtual void writeState(double timevalue) override
int getBatchIndex() const
Definition: MPIBlock.hpp:171
int getStartBatch() const
Definition: MPIBlock.hpp:156
int getRowIndex() const
Definition: MPIBlock.hpp:161
int getNumValues()
Definition: BaseProbe.hpp:61
virtual void initOutputStreams(const char *filename, Checkpointer *checkpointer) override
Definition: PointProbe.cpp:121
virtual Response::Status outputState(double timef) override
Definition: PointProbe.cpp:164
const float * getLayerData(int delay=0)
std::string makeOutputPathFilename(std::string const &path)