PetaVision  Alpha
buildandrun.cpp
1 /*
2  * buildandrun.cpp
3  *
4  * buildandrun() builds the layers, connections, and
5  * (to a limited extent) probes from the params file and then calls the
6  * hypercol's run method.
7  * It deletes the PV_Init and HyPerCol objects that it creates.
8  * Often, the main() function consists only of a call to buildandrun.
9  *
10  * outputParams(argc, argv, path, factory) builds the
11  * layers, connections, etc. and then calls the hypercol's processParams
12  * method, which fills in default parameters, ignores unnecessary parameters
13  * and sends the parameters to the file specified in the path argument.
14  * Relative paths are relative to the params file outputParams deletes the
15  * PV_Init and HyPerCol objects that it creates; it is written to be a
16  * stand-alone function to create a cleaned-up params file.
17  *
18  * build() builds the hypercol but does not run it. That way additional objects
19  * can be created and added by hand if they are not yet supported by build().
20  *
21  * Created on: May 27, 2011
22  * Author: peteschultz
23  */
24 
25 #include "buildandrun.hpp"
26 
27 using namespace PV;
28 
29 // The buildandrun, rebuildandrun, and buildandrun1paramset functions below
30 // automate creating the HyPerCol, filling it with layers, connections, etc.,
31 // and running it. To add custom groups, instantiate a PV_Init object
32 // and call PV_Init::registerKeyword with the create function (in most cases,
33 // the static function template PV::Factory::create<CustomClass>.
34 int buildandrun(
35  int argc,
36  char *argv[],
37  int (*custominit)(HyPerCol *, int, char **),
38  int (*customexit)(HyPerCol *, int, char **)) {
39  PV_Init initObj(&argc, &argv, false /*value of allowUnrecognizedArguments*/);
40  int status = buildandrun(&initObj, custominit, customexit);
41  return status;
42 }
43 
44 int buildandrun(
45  PV_Init *initObj,
46  int (*custominit)(HyPerCol *, int, char **),
47  int (*customexit)(HyPerCol *, int, char **)) {
48  if (initObj->isExtraProc()) {
49  return 0;
50  }
51  PVParams *params = initObj->getParams();
52  if (params == NULL) {
53  if (initObj->getWorldRank() == 0) {
54  char const *progName = initObj->getProgramName();
55  if (progName == NULL) {
56  progName = "PetaVision";
57  }
58  ErrorLog().printf("%s was called without having set a params file\n", progName);
59  }
60  MPI_Barrier(initObj->getCommunicator()->communicator());
61  exit(EXIT_FAILURE);
62  }
63 
64  int numParamSweepValues = initObj->getParams()->getParameterSweepSize();
65 
66  int status = PV_SUCCESS;
67  if (numParamSweepValues) {
68  for (int k = 0; k < numParamSweepValues; k++) {
69  if (initObj->getWorldRank() == 0) {
70  InfoLog().printf(
71  "Parameter sweep: starting run %d of %d\n", k + 1, numParamSweepValues);
72  }
73  status = buildandrun1paramset(initObj, custominit, customexit, k) == PV_SUCCESS
74  ? status
75  : PV_FAILURE;
76  }
77  }
78  else {
79  status = buildandrun1paramset(initObj, custominit, customexit) == PV_SUCCESS ? status
80  : PV_FAILURE;
81  }
82 
83  return status;
84 }
85 
86 // A synonym for the form of buildandrun() that takes a PV_Init object.
87 // It is older than that form, and has been kept for backwards compatibility.
88 int rebuildandrun(
89  PV_Init *initObj,
90  int (*custominit)(HyPerCol *, int, char **),
91  int (*customexit)(HyPerCol *, int, char **)) {
92  return buildandrun(initObj, custominit, customexit);
93 }
94 
95 int buildandrun1paramset(
96  PV_Init *initObj,
97  int (*custominit)(HyPerCol *, int, char **),
98  int (*customexit)(HyPerCol *, int, char **),
99  int sweepindex) {
100  if (sweepindex >= 0) {
101  initObj->getParams()->setParameterSweepValues(sweepindex);
102  }
103  HyPerCol *hc = new HyPerCol(initObj);
104 
105  int status = PV_SUCCESS;
106  int argc = 0;
107  char **argv = NULL;
108  if (custominit || customexit) {
109  argc = initObj->getNumArgs();
110  argv = initObj->getArgsCopy();
111  }
112  if (custominit != NULL) {
113  status = (*custominit)(hc, argc, argv);
114  if (status != PV_SUCCESS) {
115  ErrorLog().printf("custominit function failed with return value %d\n", status);
116  }
117  }
118 
119  if (status == PV_SUCCESS && hc->getFinalStep() > 0L) {
120  status = hc->run();
121  if (status != PV_SUCCESS) {
122  ErrorLog().printf("HyPerCol::run() returned with error code %d\n", status);
123  }
124  }
125  if (status == PV_SUCCESS && customexit != NULL) {
126  status = (*customexit)(hc, argc, argv);
127  if (status != PV_SUCCESS) {
128  ErrorLog().printf("customexit function failed with return value %d\n", status);
129  }
130  }
131  if (custominit || customexit) {
132  initObj->freeArgs(argc, argv);
133  }
134  delete hc; /* HyPerCol's destructor takes care of deleting layers and
135  connections */
136  return status;
137 }
138 
139 HyPerCol *build(PV_Init *initObj) { return initObj ? new HyPerCol(initObj) : nullptr; }
static void freeArgs(int argc, char **argv)
Definition: PV_Init.cpp:275
int getNumArgs() const
Definition: PV_Init.hpp:77
PVParams * getParams()
Definition: PV_Init.hpp:114
char ** getArgsCopy() const
Definition: PV_Init.cpp:251
char const * getProgramName() const
Definition: PV_Init.hpp:82