summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGard Spreemann <gard.spreemann@epfl.ch>2018-10-24 13:07:52 +0200
committerGard Spreemann <gard.spreemann@epfl.ch>2018-10-24 13:07:52 +0200
commit3ae1f6c19533f24964166ec373e739c82919ae75 (patch)
treeef1c23301612a01e449f7db29b571b666b58141f
parent864389f80dc5e7bdfa936c73c5f792b993a2b971 (diff)
Proper option parsing.
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/main.cpp24
-rw-r--r--src/options.cpp97
-rw-r--r--src/options.hpp17
4 files changed, 132 insertions, 8 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ecff6e3..f6002e7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,2 +1,2 @@
-add_executable(lapdog main.cpp)
+add_executable(lapdog main.cpp options.cpp)
target_link_libraries(lapdog ${MPI_LIBRARIES} ${PETSC_LIBRARIES} ${SLEPC_LIBRARIES})
diff --git a/src/main.cpp b/src/main.cpp
index 8d09427..d1dc8b1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -5,13 +5,22 @@
#include <slepceps.h>
#include <petscmat.h>
+#include "options.hpp"
+
int main(int argc, char ** argv)
{
SlepcInitialize(&argc, &argv, NULL, NULL);
- std::string infile(argv[1]);
- std::string outfile_vals(argv[2]);
- std::string outfile_vecs(argv[3]);
+ Options opts;
+ int optresult = parse_opts(argc, argv, opts);
+ if (optresult)
+ {
+ SlepcFinalize();
+ if (optresult == 2)
+ exit(0);
+ else
+ exit(1);
+ }
PetscMPIInt mpi_rank;
PetscMPIInt mpi_size;
@@ -19,15 +28,16 @@ int main(int argc, char ** argv)
MPI_Comm_size(PETSC_COMM_WORLD, &mpi_size);
PetscErrorCode err;
+
Mat L;
err = MatCreate(PETSC_COMM_WORLD, &L); CHKERRQ(err);
err = MatSetFromOptions(L); CHKERRQ(err);
PetscViewer viewer;
- err = PetscViewerBinaryOpen(PETSC_COMM_WORLD, infile.c_str(), FILE_MODE_READ, &viewer); CHKERRQ(err);
+ err = PetscViewerBinaryOpen(PETSC_COMM_WORLD, opts.infile.c_str(), FILE_MODE_READ, &viewer); CHKERRQ(err);
err = MatLoad(L, viewer); CHKERRQ(err);
err = MatAssemblyBegin(L, MAT_FINAL_ASSEMBLY); CHKERRQ(err);
- err = MatAssemblyEnd(L, MAT_FINAL_ASSEMBLY); CHKERRQ(err);
+ err = MatAssemblyEnd(L, MAT_FINAL_ASSEMBLY); CHKERRQ(err);
PetscInt m;
PetscInt n;
@@ -86,8 +96,8 @@ int main(int argc, char ** argv)
std::ofstream ofs_vecs;
if (mpi_rank == 0)
{
- ofs_vals.open(outfile_vals, std::ios::out);
- ofs_vecs.open(outfile_vecs, std::ios::out);
+ ofs_vals.open(opts.outfile_vals, std::ios::out);
+ ofs_vecs.open(opts.outfile_vecs, std::ios::out);
}
for (PetscInt i = 0; i < num_ev; i++)
diff --git a/src/options.cpp b/src/options.cpp
new file mode 100644
index 0000000..a52a0bc
--- /dev/null
+++ b/src/options.cpp
@@ -0,0 +1,97 @@
+#include <string>
+#include <iostream>
+
+#include "options.hpp"
+
+void print_usage(const std::string & invocation)
+{
+ std::cerr << "Usage:" << std::endl;
+ std::cerr << invocation << " " << usage_args << std::endl;
+}
+
+void print_help(const std::string & invocation)
+{
+ print_usage(invocation);
+ std::cerr << "FIXME: Write help." << std::endl;
+}
+
+int parse_opts(int argc, char ** argv, Options & opts)
+{
+ std::string invocation(argv[0]);
+
+ for (int i = 1; i < argc; ++i)
+ {
+ std::string arg(argv[i]);
+
+ if (arg == std::string("-h") || arg == std::string("--help"))
+ {
+ print_help(invocation);
+ return 2;
+ }
+
+ else if (arg == std::string("-l") || arg == std::string("--laplacian"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ opts.infile = std::string(argv[++i]);
+ else
+ {
+ std::cerr << "Missing argument to --laplacian." << std::endl;
+ print_usage(invocation);
+ return 1;
+ }
+ }
+
+ else if (arg == std::string("--vals"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ opts.outfile_vals = std::string(argv[++i]);
+ else
+ {
+ std::cerr << "Missing argument to --vals." << std::endl;
+ print_usage(invocation);
+ return 1;
+ }
+ }
+
+ else if (arg == std::string("--vecs"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ opts.outfile_vecs = std::string(argv[++i]);
+ else
+ {
+ std::cerr << "Missing argument to --vecs." << std::endl;
+ print_usage(invocation);
+ return 1;
+ }
+ }
+
+ else
+ {
+ std::cout << "The argument \"" << arg << "\" will be dealt with by PETSc/SLEPc if they understand it. Otherwise it will be silently ignored." << std::endl;
+ }
+ }
+
+ // Begin options validation.
+ if (opts.infile.empty())
+ {
+ std::cerr << "Missing Laplacian file." << std::endl;
+ print_usage(invocation);
+ return 1;
+ }
+
+ if (opts.outfile_vecs.empty())
+ {
+ std::cerr << "Missing output eigenvectors file." << std::endl;
+ print_usage(invocation);
+ return 1;
+ }
+ if (opts.outfile_vals.empty())
+ {
+ std::cerr << "Missing output eigenvalues file." << std::endl;
+ print_usage(invocation);
+ return 1;
+ }
+ // End validation.
+
+ return 0;
+}
diff --git a/src/options.hpp b/src/options.hpp
new file mode 100644
index 0000000..05a6ee5
--- /dev/null
+++ b/src/options.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <string>
+
+typedef struct Options
+{
+ std::string infile;
+ std::string outfile_vals;
+ std::string outfile_vecs;
+} Options;
+
+int parse_opts(int argc, char ** argv, Options & opts);
+
+void print_usage(const std::string & invocation);
+void print_help(const std::string & invocation);
+
+static const std::string usage_args("--laplacian|-l file --vals file --vecs file [-h|--help] [PETSc/SLEPc options]");