PetaVision  Alpha
io.cpp
1 /*
2  * io.c
3  *
4  * Created on: Aug 3, 2008
5  * Author: dcoates
6  */
7 
8 // Shared input and output routines
9 
10 #include "io.hpp"
11 
12 #include <assert.h>
13 #include <cmath>
14 #include <float.h> // FLT_MAX/MIN
15 #include <string.h> // memcpy
16 #include <string>
17 
18 #include "utils/PVLog.hpp"
19 
20 namespace PV {
21 
22 void usage() {
23  InfoLog().printf("\nUsage:\n");
24  InfoLog().printf(" -p <parameters filename>\n");
25  InfoLog().printf(" [-o <output directory>\n");
26  InfoLog().printf(" [-s <random number generator seed>]\n");
27  InfoLog().printf(" [-d [<GPU device>,<GPU device>,...]]\n");
28  InfoLog().printf(" [-l <output log file>]\n");
29  InfoLog().printf(" [-w <working directory>]\n");
30  InfoLog().printf(" [-r|-c <checkpoint directory>]\n");
31 #ifdef PV_USE_OPENMP_THREADS
32  InfoLog().printf(" [-t [number of threads]\n");
33  InfoLog().printf(" [-n]\n");
34 #endif // PV_USE_OPENMP_THREADS
35 }
36 
45 int parse_options(
46  int argc,
47  char const *const *argv,
48  bool *paramusage,
49  bool *require_return,
50  char **output_path,
51  char **param_file,
52  char **log_file,
53  char **gpu_devices,
54  unsigned int *random_seed,
55  char **working_dir,
56  int *restart,
57  char **checkpointReadDir,
58  bool *useDefaultNumThreads,
59  int *numthreads,
60  int *num_rows,
61  int *num_columns,
62  int *batch_width,
63  int *dry_run) {
64  paramusage[0] = true;
65  int arg;
66  for (arg = 1; arg < argc; arg++) {
67  paramusage[arg] = false;
68  }
69 
70  if (pv_getopt(argc, argv, "--require-return", paramusage) == 0) {
71  *require_return = true;
72  }
73  pv_getopt_str(argc, argv, "-d", gpu_devices, paramusage);
74  pv_getoptionalopt_int(argc, argv, "-t", numthreads, useDefaultNumThreads, paramusage);
75  pv_getopt_str(argc, argv, "-o", output_path, paramusage);
76  pv_getopt_str(argc, argv, "-p", param_file, paramusage);
77  pv_getopt_str(argc, argv, "-l", log_file, paramusage);
78  pv_getopt_unsigned(argc, argv, "-s", random_seed, paramusage);
79  pv_getopt_str(argc, argv, "-w", working_dir, paramusage);
80  if (pv_getopt(argc, argv, "-r", paramusage) == 0) {
81  *restart = 1;
82  }
83  pv_getopt_str(argc, argv, "-c", checkpointReadDir, paramusage);
84  pv_getopt_int(argc, argv, "-rows", num_rows, paramusage);
85  pv_getopt_int(argc, argv, "-columns", num_columns, paramusage);
86  pv_getopt_int(argc, argv, "-batchwidth", batch_width, paramusage);
87  if (pv_getopt(argc, argv, "-n", paramusage) == 0) {
88  *dry_run = 1;
89  }
90 
91  return 0;
92 }
93 
94 /*
95  * @argc
96  * @argv
97  * @opt
98  */
99 int pv_getopt(int argc, char const *const *argv, char const *opt, bool *paramusage) {
100  int i;
101  for (i = 1; i < argc; i++) {
102  if (strcmp(argv[i], opt) == 0) {
103  if (paramusage) {
104  paramusage[i] = true;
105  }
106  return 0;
107  }
108  }
109  return -1; // not found
110 }
111 
118 int pv_getopt_int(int argc, char const *const *argv, char const *opt, int *iVal, bool *paramusage) {
119  int i;
120  for (i = 1; i < argc; i += 1) {
121  if (i + 1 < argc && strcmp(argv[i], opt) == 0) {
122  if (iVal != NULL)
123  *iVal = atoi(argv[i + 1]);
124  if (paramusage) {
125  paramusage[i] = true;
126  paramusage[i + 1] = true;
127  }
128  return 0;
129  }
130  }
131  return -1; // not found
132 }
133 
134 int pv_getoptionalopt_int(
135  int argc,
136  char const *const *argv,
137  char const *opt,
138  int *iVal,
139  bool *useDefaultVal,
140  bool *paramusage) {
141  int i;
142  for (i = 1; i < argc; i += 1) {
143  if (strcmp(argv[i], opt) == 0) {
144  // Default parameter
145  if (i + 1 >= argc || argv[i + 1][0] == '-') {
146  if (iVal != NULL) {
147  *iVal = -1;
148  }
149  if (useDefaultVal != NULL) {
150  *useDefaultVal = true;
151  }
152  if (paramusage) {
153  paramusage[i] = true;
154  }
155  }
156  else {
157  if (iVal != NULL) {
158  *iVal = atoi(argv[i + 1]);
159  }
160  if (useDefaultVal != NULL) {
161  *useDefaultVal = false;
162  }
163  if (paramusage) {
164  paramusage[i] = true;
165  paramusage[i + 1] = true;
166  }
167  }
168  return 0;
169  }
170  }
171  if (iVal != NULL) {
172  *iVal = -1;
173  }
174  if (useDefaultVal != NULL) {
175  *useDefaultVal = false;
176  }
177  return -1; // not found
178 }
179 
186 int pv_getopt_long(
187  int argc,
188  char const *const *argv,
189  char const *opt,
190  long int *iVal,
191  bool *paramusage) {
192  int i;
193  for (i = 1; i < argc; i += 1) {
194  if (i + 1 < argc && strcmp(argv[i], opt) == 0) {
195  if (iVal != NULL)
196  *iVal = strtol(argv[i + 1], NULL, 0);
197  if (paramusage) {
198  paramusage[i] = true;
199  paramusage[i + 1] = true;
200  }
201  return 0;
202  }
203  }
204  return -1; // not found
205 }
206 
213 int pv_getopt_unsigned(
214  int argc,
215  char const *const *argv,
216  char const *opt,
217  unsigned int *uVal,
218  bool *paramusage) {
219  int i;
220  for (i = 1; i < argc; i += 1) {
221  if (i + 1 < argc && strcmp(argv[i], opt) == 0) {
222  if (uVal != NULL)
223  *uVal = (unsigned int)strtoul(argv[i + 1], NULL, 0);
224  if (paramusage) {
225  paramusage[i] = true;
226  paramusage[i + 1] = true;
227  }
228  return 0;
229  }
230  }
231  return -1; // not found
232 }
233 
240 int pv_getopt_str(
241  int argc,
242  char const *const *argv,
243  char const *opt,
244  char **sVal,
245  bool *paramusage) {
246  // sVal can be NULL. If sVal is not null and the option is found,
247  // the value of the option is put into sVal and the calling routine is
248  // responsible for freeing it.
249  // Example: if argv[1] is "-p" and argv[2] is "params.pv", and opt is "-p",
250  // *sVal will be "params.pv".
251  int i;
252  for (i = 1; i < argc; i += 1) {
253  if (i + 1 < argc && strcmp(argv[i], opt) == 0) {
254  if (sVal != NULL)
255  *sVal = strdup(argv[i + 1]);
256  if (paramusage) {
257  paramusage[i] = true;
258  paramusage[i + 1] = true;
259  }
260  return 0;
261  }
262  }
263  if (sVal != NULL)
264  *sVal = NULL;
265  return -1; // not found
266 }
267 
268 std::string expandLeadingTilde(std::string const &path) { return expandLeadingTilde(path.c_str()); }
269 
270 std::string expandLeadingTilde(char const *path) {
271  if (path == NULL) {
272  return std::string("");
273  }
274  char *newpath = NULL;
275  if (path != NULL) {
276  int len = strlen(path);
277  if (len == 1 && path[0] == '~') {
278  newpath = strdup(getenv("HOME"));
279  if (newpath == NULL) {
280  Fatal().printf(
281  "Unable to expand \"%s\": "
282  "home directory not defined\n",
283  path);
284  exit(EXIT_FAILURE);
285  }
286  }
287  else if (len > 1 && path[0] == '~' && path[1] == '/') {
288  char *homedir = getenv("HOME");
289  if (homedir == NULL) {
290  Fatal().printf(
291  "Unable to expand \"%s\": "
292  "home directory not defined\n",
293  path);
294  }
295  char dummy;
296  int chars_needed = snprintf(&dummy, 0, "%s/%s", homedir, &path[2]);
297  newpath = (char *)malloc(chars_needed + 1);
298  if (newpath == NULL) {
299  Fatal().printf("Unable to allocate memory for path \"%s/%s\"\n", homedir, &path[2]);
300  }
301  int chars_used = snprintf(newpath, chars_needed + 1, "%s/%s", homedir, &path[2]);
302  assert(chars_used == chars_needed);
303  }
304  else {
305  newpath = strdup(path);
306  }
307  }
308  FatalIf(newpath == NULL, "Could not expand path: %s\n", path);
309  std::string result(newpath);
310  free(newpath);
311  return result;
312 }
313 
314 } // namespace PV