You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
3.8 KiB

2 years ago
  1. /*****************************************************************************
  2. *
  3. * demo program - part of CLIPP (command line interfaces for modern C++)
  4. *
  5. * released under MIT license
  6. *
  7. * (c) 2017-2018 André Müller; foss@andremueller-online.de
  8. *
  9. *****************************************************************************/
  10. #include <iostream>
  11. #include <stdexcept>
  12. #include <string>
  13. #include <vector>
  14. #include <clipp.h>
  15. //-------------------------------------------------------------------
  16. enum class mode {
  17. none, train, validate, classify
  18. };
  19. struct settings {
  20. mode selected = mode::none;
  21. std::string imageFile;
  22. std::string labelFile;
  23. std::string modelFile = "out.mdl";
  24. std::size_t batchSize = 128;
  25. std::size_t threads = 0;
  26. std::size_t inputLimit = 0;
  27. std::vector<std::string> inputFiles;
  28. };
  29. //-------------------------------------------------------------------
  30. settings configuration(int argc, char* argv[])
  31. {
  32. using namespace clipp;
  33. settings s;
  34. std::vector<std::string> unrecognized;
  35. auto isfilename = clipp::match::prefix_not("-");
  36. auto inputOptions = (
  37. required("-i", "-I", "--img") & !value(isfilename, "image file", s.imageFile),
  38. required("-l", "-L", "--lbl") & !value(isfilename, "label file", s.labelFile)
  39. );
  40. auto trainMode = (
  41. command("train", "t", "T").set(s.selected,mode::train)
  42. .if_conflicted([]{std::cerr << "conflicting modes\n"; }),
  43. inputOptions,
  44. (option("-n") & integer("limit", s.inputLimit))
  45. % "limit number of input images",
  46. (option("-o", "-O", "--out") & !value("model file", s.modelFile))
  47. % "write model to specific file; default: 'out.mdl'",
  48. (option("-b", "--batch-size") & integer("batch size", s.batchSize)),
  49. (option("-p") & integer("threads", s.threads))
  50. % "number of threads to use; default: optimum for machine"
  51. );
  52. auto validationMode = (
  53. command("validate", "v", "V").set(s.selected,mode::validate),
  54. !value(isfilename, "model", s.modelFile),
  55. inputOptions
  56. );
  57. auto classificationMode = (
  58. command("classify", "c", "C").set(s.selected,mode::classify),
  59. !value(isfilename, "model", s.modelFile),
  60. !values(isfilename, "images", s.inputFiles)
  61. );
  62. auto cli = (
  63. trainMode | validationMode | classificationMode,
  64. any_other(unrecognized)
  65. );
  66. auto res = parse(argc, argv, cli);
  67. debug::print(std::cout, res);
  68. if(!res || !unrecognized.empty()) {
  69. std::string msg = "Wrong command line arguments!\n";
  70. if(s.selected == mode::none) {
  71. msg += "Please select a mode!\n";
  72. }
  73. else {
  74. for(const auto& m : res.missing()) {
  75. if(!m.param()->flags().empty()) {
  76. msg += "Missing option: " + m.param()->flags().front() + '\n';
  77. }
  78. else if(!m.param()->label().empty()) {
  79. msg += "Missing value: " + m.param()->label() + '\n';
  80. }
  81. }
  82. for(const auto& arg : unrecognized) {
  83. msg += "Argument not recognized: " + arg + '\n';
  84. }
  85. }
  86. auto fmt = doc_formatting{}.first_column(8).doc_column(16);
  87. //.max_flags_per_param_in_usage(3).surround_alternative_flags("(", ")");
  88. msg += "\nUsage:\n" + usage_lines(cli, argv[0], fmt).str() + '\n';
  89. msg += "\nOptions:\n" + documentation(cli, fmt).str() + '\n';
  90. throw std::invalid_argument{msg};
  91. }
  92. return s;
  93. }
  94. //-------------------------------------------------------------------
  95. int main(int argc, char* argv[])
  96. {
  97. try {
  98. auto conf = configuration(argc, argv);
  99. std::cout << "SUCCESS\n";
  100. }
  101. catch(std::exception& e) {
  102. std::cerr << "ERROR: " << e.what() << '\n';
  103. }
  104. }