PetaVision  Alpha
AdaptiveTimeScaleProbe.cpp
1 /*
2  * AdaptiveTimeScaleProbe.cpp
3  *
4  * Created on: Aug 18, 2016
5  * Author: pschultz
6  */
7 
8 #include "AdaptiveTimeScaleProbe.hpp"
9 #include "columns/Messages.hpp"
10 
11 namespace PV {
12 
13 AdaptiveTimeScaleProbe::AdaptiveTimeScaleProbe(char const *name, HyPerCol *hc) {
14  initialize(name, hc);
15 }
16 
17 AdaptiveTimeScaleProbe::AdaptiveTimeScaleProbe() {}
18 
19 AdaptiveTimeScaleProbe::~AdaptiveTimeScaleProbe() { delete mAdaptiveTimeScaleController; }
20 
21 int AdaptiveTimeScaleProbe::initialize(char const *name, HyPerCol *hc) {
22  int status = ColProbe::initialize(name, hc);
23  return status;
24 }
25 
26 int AdaptiveTimeScaleProbe::ioParamsFillGroup(enum ParamsIOFlag ioFlag) {
27  int status = ColProbe::ioParamsFillGroup(ioFlag);
28  ioParam_baseMax(ioFlag);
29  ioParam_baseMin(ioFlag);
30  ioParam_tauFactor(ioFlag);
31  ioParam_growthFactor(ioFlag);
34  return status;
35 }
36 
37 void AdaptiveTimeScaleProbe::ioParam_targetName(enum ParamsIOFlag ioFlag) {
38  parent->parameters()->ioParamStringRequired(ioFlag, name, "targetName", &targetName);
39 }
40 
41 void AdaptiveTimeScaleProbe::ioParam_baseMax(enum ParamsIOFlag ioFlag) {
42  parent->parameters()->ioParamValue(ioFlag, name, "baseMax", &mBaseMax, mBaseMax);
43 }
44 
45 void AdaptiveTimeScaleProbe::ioParam_baseMin(enum ParamsIOFlag ioFlag) {
46  parent->parameters()->ioParamValue(ioFlag, name, "baseMin", &mBaseMin, mBaseMin);
47 }
48 
49 void AdaptiveTimeScaleProbe::ioParam_tauFactor(enum ParamsIOFlag ioFlag) {
50  parent->parameters()->ioParamValue(ioFlag, name, "tauFactor", &tauFactor, tauFactor);
51 }
52 
53 void AdaptiveTimeScaleProbe::ioParam_growthFactor(enum ParamsIOFlag ioFlag) {
54  parent->parameters()->ioParamValue(ioFlag, name, "growthFactor", &mGrowthFactor, mGrowthFactor);
55 }
56 
57 // writeTimeScales was marked obsolete Jul 27, 2017. Use textOutputFlag instead.
58 void AdaptiveTimeScaleProbe::ioParam_writeTimeScales(enum ParamsIOFlag ioFlag) {
59  if (ioFlag != PARAMS_IO_READ) {
60  return;
61  }
62  pvAssert(!parent->parameters()->presentAndNotBeenRead(name, "textOutputFlag"));
63  if (parent->parameters()->present(name, "writeTimeScales")) {
64  bool writeTimeScales = (parent->parameters()->value(name, "writeTimeScales") != 0);
65  if (writeTimeScales == getTextOutputFlag()) {
66  WarnLog() << getDescription()
67  << " sets writeTimeScales, which is obsolete. Use textOutputFlag instead.\n";
68  }
69  else if (parent->parameters()->present(name, "textOutputFlag")) {
70  Fatal() << "writeTimeScales is obsolete as it is redundant with textOutputFlag. "
71  << getDescription() << " sets these flags to opposite values.\n";
72  }
73  else {
74  pvAssert(writeTimeScales != getTextOutputFlag());
75  Fatal() << "writeTimeScales is obsolete as it is redundant with textOutputFlag. "
76  << getDescription() << " sets writeTimeScales to "
77  << (writeTimeScales ? "true" : "false")
78  << " but the default value of textOutputFlag is "
79  << (getTextOutputFlag() ? "true" : "false") << "\n";
80  }
81  }
82 }
83 
85  pvAssert(!parent->parameters()->presentAndNotBeenRead(name, "textOutputFlag"));
86  if (getTextOutputFlag()) {
87  parent->parameters()->ioParamValue(
88  ioFlag,
89  name,
90  "writeTimeScaleFieldnames",
91  &mWriteTimeScaleFieldnames,
92  mWriteTimeScaleFieldnames);
93  }
94 }
95 
97  std::shared_ptr<CommunicateInitInfoMessage const> message) {
98  auto status = ColProbe::communicateInitInfo(message);
99  if (!Response::completed(status)) {
100  return status;
101  }
102  mTargetProbe = message->lookup<BaseProbe>(std::string(targetName));
103  if (mTargetProbe == nullptr) {
104  if (parent->getCommunicator()->commRank() == 0) {
105  Fatal() << getDescription() << ": targetName \"" << targetName
106  << "\" is not a probe in the HyPerCol.\n";
107  }
108  MPI_Barrier(parent->getCommunicator()->communicator());
109  exit(EXIT_FAILURE);
110  }
111  return Response::SUCCESS;
112 }
113 
114 Response::Status AdaptiveTimeScaleProbe::allocateDataStructures() {
115  auto status = ColProbe::allocateDataStructures();
116  if (!Response::completed(status)) {
117  return status;
118  }
119  if (mTargetProbe->getNumValues() != getNumValues()) {
120  if (parent->getCommunicator()->commRank() == 0) {
121  Fatal() << getDescription() << ": target probe \"" << mTargetProbe->getDescription()
122  << "\" does not have the correct numValues (" << mTargetProbe->getNumValues()
123  << " instead of " << getNumValues() << ").\n";
124  }
125  MPI_Barrier(parent->getCommunicator()->communicator());
126  exit(EXIT_FAILURE);
127  }
128  allocateTimeScaleController();
129  return Response::SUCCESS;
130 }
131 
132 void AdaptiveTimeScaleProbe::allocateTimeScaleController() {
133  mAdaptiveTimeScaleController = new AdaptiveTimeScaleController(
134  getName(),
135  getNumValues(),
136  mBaseMax,
137  mBaseMin,
138  tauFactor,
139  mGrowthFactor,
140  mWriteTimeScaleFieldnames,
141  parent->getCommunicator());
142 }
143 
144 Response::Status AdaptiveTimeScaleProbe::registerData(Checkpointer *checkpointer) {
145  auto status = ColProbe::registerData(checkpointer);
146  if (!Response::completed(status)) {
147  return status;
148  }
149  mAdaptiveTimeScaleController->registerData(checkpointer);
150  return Response::SUCCESS;
151 }
152 
153 Response::Status AdaptiveTimeScaleProbe::respond(std::shared_ptr<BaseMessage const> message) {
154  Response::Status status = ColProbe::respond(message);
155  if (message == nullptr) {
156  return status;
157  }
158  else if (auto castMessage = std::dynamic_pointer_cast<AdaptTimestepMessage const>(message)) {
159  return respondAdaptTimestep(castMessage);
160  }
161  else {
162  return status;
163  }
164 }
165 
166 Response::Status
167 AdaptiveTimeScaleProbe::respondAdaptTimestep(std::shared_ptr<AdaptTimestepMessage const> message) {
168  getValues(parent->simulationTime());
169  return Response::SUCCESS;
170 }
171 
172 // AdaptiveTimeScaleProbe::calcValues calls targetProbe->getValues() and passes the result to
173 // mAdaptiveTimeScaleController->calcTimesteps() to use as timeScaleTrue.
174 // mAdaptiveTimeScaleController->calcTimesteps() returns timeScale and copies the result into
175 // probeValues. AdaptiveTimeScaleProbe also processes the triggering and only reads the
176 // mAdaptiveTimeScaleController when triggering doesn't happen.
177 
178 void AdaptiveTimeScaleProbe::calcValues(double timeValue) {
179  std::vector<double> rawProbeValues;
180  if (triggerLayer != nullptr
181  && triggerLayer->needUpdate(timeValue + triggerOffset, parent->getDeltaTime())) {
182  rawProbeValues.assign(getNumValues(), -1.0);
183  }
184  else {
185  mTargetProbe->getValues(timeValue, &rawProbeValues);
186  }
187  pvAssert(rawProbeValues.size() == getNumValues()); // In allocateDataStructures, we checked that
188  // mTargetProbe has a compatible size.
189  std::vector<double> timeSteps =
190  mAdaptiveTimeScaleController->calcTimesteps(timeValue, rawProbeValues);
191  memcpy(getValuesBuffer(), timeSteps.data(), sizeof(double) * getNumValues());
192 }
193 
194 Response::Status AdaptiveTimeScaleProbe::outputState(double timeValue) {
195  if (!mOutputStreams.empty()) {
196  mAdaptiveTimeScaleController->writeTimestepInfo(timeValue, mOutputStreams);
197  }
198  return Response::SUCCESS;
199 }
200 
201 } /* namespace PV */
int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
virtual void ioParam_baseMin(enum ParamsIOFlag ioFlag)
baseMin: Specifies the minimum timescale allowed.
virtual void ioParam_tauFactor(enum ParamsIOFlag ioFlag)
tauFactor: If Specifies the coefficient on the effective decay rate used to compute the timescale...
virtual void calcValues(double timeValue) override
int present(const char *groupName, const char *paramName)
Definition: PVParams.cpp:1254
virtual void ioParam_baseMax(enum ParamsIOFlag ioFlag)
baseMax: Specifies the initial maximum timescale allowed. The maximum timescale is allowed to increas...
double value(const char *groupName, const char *paramName)
Definition: PVParams.cpp:1270
virtual void ioParam_targetName(enum ParamsIOFlag ioFlag) override
targetName: the name of the probe that this probe attaches to. The target probe&#39;s values are used as ...
static bool completed(Status &a)
Definition: Response.hpp:49
virtual void ioParam_growthFactor(enum ParamsIOFlag ioFlag)
dtChangeMin: Specifies the percentage by which the maximum timescale increases when the timescale rea...
int initialize(const char *name, HyPerCol *hc)
Definition: ColProbe.cpp:31
double * getValuesBuffer()
Definition: BaseProbe.hpp:319
virtual void ioParam_writeTimeScaleFieldnames(enum ParamsIOFlag ioFlag)
writeTimeScaleFieldnames: A flag to determine if fieldnames are written to the HyPerCol_timescales fi...
virtual bool needUpdate(double simTime, double dt)
virtual Response::Status communicateInitInfo(std::shared_ptr< CommunicateInitInfoMessage const > message) override
virtual Response::Status registerData(Checkpointer *checkpointer) override
Definition: BaseProbe.cpp:320
void getValues(double timevalue, double *valuesVector)
Definition: BaseProbe.cpp:336
virtual Response::Status registerData(Checkpointer *checkpointer) override
virtual Response::Status outputState(double timeValue) override
virtual Response::Status communicateInitInfo(std::shared_ptr< CommunicateInitInfoMessage const > message) override
Definition: ColProbe.cpp:82
int getNumValues()
Definition: BaseProbe.hpp:61
bool getTextOutputFlag() const
Definition: BaseProbe.hpp:324
virtual void ioParam_writeTimeScales(enum ParamsIOFlag ioFlag)
writeTimeScales is obsolete, as it is redundant with textOutputFlag.
virtual int ioParamsFillGroup(enum ParamsIOFlag ioFlag) override
Definition: ColProbe.cpp:36