| // |
| // Copyright © 2017 Arm Ltd. All rights reserved. |
| // SPDX-License-Identifier: MIT |
| // |
| |
| #include <Filesystem.hpp> |
| #include <cxxopts/cxxopts.hpp> |
| |
| #include <algorithm> |
| #include <fstream> |
| #include <iostream> |
| #include <string> |
| |
| namespace |
| { |
| |
| // parses the command line to extract |
| // * the directory -i to look through .raw files from (must exist) |
| // * the name of the file -o the output CSV file path (must not already exist) |
| class CommandLineProcessor |
| { |
| public: |
| bool ParseOptions(cxxopts::ParseResult& result) |
| { |
| // indir is mandatory, dir could possibly be changed. |
| if (result.count("indir")) |
| { |
| std::string dir = result["indir"].as<std::string>(); |
| |
| if (!ValidateDirectory(dir)) |
| { |
| return false; |
| } |
| |
| m_InputDirectory = dir; |
| } |
| else |
| { |
| std::cerr << "-i/--indir parameter is mandatory." << std::endl; |
| return false; |
| } |
| |
| // outfile is mandatory |
| if (result.count("outfile")) |
| { |
| if (!ValidateOutputFile(result["outfile"].as<std::string>())) |
| { |
| return false; |
| } |
| } |
| else |
| { |
| std::cerr << "-o/--outfile parameter is mandatory." << std::endl; |
| return false; |
| } |
| |
| if (result.count("layer-binding-id")) |
| { |
| if(!ValidateBindingId(result["layer-binding-id"].as<std::string>())) |
| { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool ValidateDirectory(std::string& dir) |
| { |
| if (dir.empty()) |
| { |
| std::cerr << "No directory specified" << std::endl; |
| return false; |
| } |
| |
| if (dir[dir.length() - 1] != '/') |
| { |
| dir += "/"; |
| } |
| |
| if (!fs::exists(dir)) |
| { |
| std::cerr << "Directory [" << dir << "] does not exist" << std::endl; |
| return false; |
| } |
| |
| if (!fs::is_directory(dir)) |
| { |
| std::cerr << "Given directory [" << dir << "] is not a directory" << std::endl; |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateOutputFile(const std::string& outputFileName) |
| { |
| if (outputFileName.empty()) |
| { |
| std::cerr << "No output file name specified" << std::endl; |
| return false; |
| } |
| |
| if (fs::exists(outputFileName)) |
| { |
| std::cerr << "Output file [" << outputFileName << "] already exists" << std::endl; |
| return false; |
| } |
| |
| if (fs::is_directory(outputFileName)) |
| { |
| std::cerr << "Output file [" << outputFileName << "] is a directory" << std::endl; |
| return false; |
| } |
| |
| fs::path outputPath(outputFileName); |
| if (!fs::exists(outputPath.parent_path())) |
| { |
| std::cerr << "Directory [" << outputPath.parent_path().c_str() << "] does not exist" << std::endl; |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ValidateBindingId(const std::string& id) |
| { |
| if (!std::all_of(id.begin(), id.end(), ::isdigit)) |
| { |
| std::cerr << "Invalid input binding Id" << std::endl; |
| return false; |
| } |
| |
| return true; |
| } |
| |
| bool ProcessCommandLine(int argc, char* argv[]) |
| { |
| try |
| { |
| cxxopts::Options options("ImageCSVFileGenerator", |
| "Program for creating a CSV file that " |
| "contains a list of .raw tensor files. " |
| "These .raw tensor files can be generated using the ImageTensorGenerator"); |
| |
| options.add_options() |
| ("h,help", "Display help messages") |
| ("i,indir", |
| "Directory that .raw files are stored in", |
| cxxopts::value<std::string>(m_InputDirectory)) |
| ("o,outfile", |
| "Output CSV file path", |
| cxxopts::value<std::string>(m_OutputFileName)) |
| ("l, layer-binding-id", |
| "Input layer binding Id, Defaults to 0", |
| cxxopts::value<std::string>(m_InputBindingId)->default_value("0")); |
| |
| auto result = options.parse(argc, argv); |
| |
| if (result.count("help")) |
| { |
| std::cout << options.help() << std::endl; |
| return false; |
| } |
| |
| // Check for mandatory parameters and validate inputs |
| if(!ParseOptions(result)){ |
| return false; |
| } |
| } |
| catch (const cxxopts::OptionException& e) |
| { |
| std::cerr << e.what() << std::endl << std::endl; |
| return false; |
| } |
| catch (const std::exception& e) |
| { |
| std::cerr << "Fatal internal error: [" << e.what() << "]" << std::endl; |
| return false; |
| } |
| |
| return true; |
| } |
| |
| std::string GetInputDirectory() {return m_InputDirectory;} |
| std::string GetOutputFileName() {return m_OutputFileName;} |
| std::string GetInputBindingId() {return m_InputBindingId;} |
| |
| private: |
| std::string m_InputDirectory; |
| std::string m_OutputFileName; |
| std::string m_InputBindingId; |
| }; |
| |
| } // namespace anonymous |
| |
| int main(int argc, char* argv[]) |
| { |
| CommandLineProcessor cmdline; |
| if (!cmdline.ProcessCommandLine(argc, argv)) |
| { |
| return -1; |
| } |
| |
| const std::string fileFormat(".raw"); |
| |
| const std::string rawDirectory(cmdline.GetInputDirectory()); |
| const std::string outputPath(cmdline.GetOutputFileName()); |
| const std::string bindingId(cmdline.GetInputBindingId()); |
| |
| std::vector<fs::path> rawFiles; |
| for (auto& entry : fs::directory_iterator(rawDirectory)) |
| { |
| if (entry.path().extension().c_str() == fileFormat) |
| { |
| rawFiles.push_back(entry.path()); |
| } |
| } |
| |
| if (!rawFiles.empty()) |
| { |
| unsigned int pass = 0; |
| std::ofstream refinementData; |
| refinementData.open(outputPath, std::ofstream::out); |
| if (refinementData.is_open()) |
| { |
| for (auto const& raw : rawFiles) |
| { |
| refinementData << pass << ", " << bindingId << ", " << raw.c_str() << "\n"; |
| if (!refinementData) |
| { |
| std::cerr << "Failed to write to output file: " << outputPath << std::endl; |
| continue; |
| } |
| ++pass; |
| } |
| refinementData.close(); |
| } |
| else |
| { |
| std::cerr << "Failed to open output file: " << outputPath << std::endl; |
| return -1; |
| } |
| } |
| else |
| { |
| std::cerr << "No matching files with the \".raw\" extension found in the directory: " |
| << rawDirectory << std::endl; |
| return -1; |
| } |
| |
| return 0; |
| } |