#endif // NNC_HDF5_SUPPORTED
+static TensorVariant readTensorFromFile(const std::string& filename, DTYPE dtype,
+ const Shape& shape) {
+ assert(dtype == DTYPE::FLOAT32);
+ std::size_t input_data_size = shape.numElements() * sizeof(float);
+
+ std::ifstream stream(filename, std::ios::in | std::ios::binary);
+ if (stream.fail())
+ throw PassException("Couldn't open file \"" + filename + "\".");
+
+ stream.seekg(0, std::ios::end);
+ std::streampos end = stream.tellg();
+ stream.seekg(0, std::ios::beg);
+ std::streampos begin = stream.tellg();
+ long file_size = end - begin;
+
+ if (static_cast<std::size_t>(file_size) != input_data_size)
+ throw PassException("File \"" + filename + "\" has incorrect size: " +
+ std::to_string(file_size) +
+ "(expected: " + std::to_string(input_data_size) + ").");
+
+ std::unique_ptr<char[]> data(new char[input_data_size]);
+ stream.read(data.get(), input_data_size);
+ if (stream.fail())
+ throw PassException("Couldn't read file \"" + filename + "\".");
+
+ return TensorVariant(dtype, shape, data.get());
+}
+
PassData InterpreterPass::run(PassData data) {
auto g = static_cast<Graph*>(data);
assert(g);
NNInterpreter interpreter;
- // Check ops
- auto inputs = g->getInputs();
-
- auto input_data = loadInput(inputs);
- for (auto inp: input_data) {
- interpreter.setInput(inp.first, inp.second);
+ for (const auto* input_op : g->getInputs()) {
+ std::string tensor_name = input_op->getName();
+ std::replace(tensor_name.begin(), tensor_name.end(), '/', '_');
+ std::string filename = cli::interInputDataDir + "/" + tensor_name + ".dat";
+ auto tensor = readTensorFromFile(filename, DTYPE::FLOAT32, input_op->getOutputShape(0));
+ interpreter.setInput(input_op->getName(), tensor);
}
+
g->accept(&interpreter);
for (auto out_node : g->getOutputs()) {
return nullptr;
}
-// Return pure file name w/o path and extension
-static std::string getFileName(std::string path) {
- size_t sep = path.find_last_of("/");
- if (sep != std::string::npos)
- path = path.substr(sep + 1, path.size() - sep - 1);
- size_t dot = path.find_last_of(".");
- // TODO: There could be node names with symbols invalid in filename: if yes we should fix it.
- if (dot != std::string::npos)
- return path.substr(0, dot);
- return path;
-}
-
-// Return input operation index with the given name
-static int getInputOp(std::string name, const std::vector<ops::InputOp*>& ops) {
- for (unsigned ndx = 0; ndx < ops.size(); ndx++) {
- if (ops[ndx]->getName() == name)
- return ndx;
- }
- throw PassException("Input file name (without extension)"
- " should be equal to model input node name");
-}
-
-std::unordered_map<std::string, TensorVariant>
-InterpreterPass::loadInput(const std::vector<ops::InputOp*>& ops) {
- std::unordered_map<std::string, TensorVariant> result;
- for (unsigned i = 0; i < ops.size(); i++) {
- // We assume that file name is equal to input node name
- auto fname = getFileName(cli::interInputData[i]);
- auto op_ndx = getInputOp(fname, ops);
- auto f = fopen(cli::interInputData[i].c_str(), "rb");
- assert (f);
- int is_error = fseek(f, 0L, SEEK_END);
- assert(!is_error);
-
- auto len = ftell(f);
- assert(len != -1);
-
- auto shape = ops[op_ndx]->getOutputShape(0);
- auto data_size = static_cast<size_t>(shape.numElements() * sizeof(float));
-
- // Check size
- if (static_cast<size_t>(len) != data_size) {
- std::stringstream info;
- info << "Wrong input file size <" << cli::interInputData[i] << "> = "
- << len << ". Should be :" << data_size;
-
- throw PassException(info.str());
- }
-
- rewind(f);
-
- std::unique_ptr<char[]> data(new char[data_size]);
- auto rlen = fread(data.get(), data_size, 1, f);
- assert(rlen == 1);
- (void)rlen;
-
- is_error = fclose(f);
- assert(is_error != EOF && "Can not close file!");
- (void)is_error;
-
- result.emplace(fname, TensorVariant(DTYPE::FLOAT32, shape, data.get()));
- }
- return result;
-}
-
-InterpreterPass::~InterpreterPass() {
- delete _out;
-}
+InterpreterPass::~InterpreterPass() = default;
} // namespace nnc
#include "support/CommandLine.h"
#include <dirent.h>
+#include <cstring>
#include <fstream>
#include <sys/types.h>
#include <unistd.h>
fclose(f);
} // checkInFile
-void checkInFiles(const Option<std::vector<std::string>> &in_files) {
- if ( in_files.empty() )
- throw BadOption("Input file name(s) should not be empty");
-
- for (auto in_file : in_files) {
- std::ifstream ifile(in_file.c_str());
- if (ifile.fail())
- throw BadOption("Cannot open file <" + in_file + ">");
- }
-} // checkInFiles
-
void checkOutFile(const Option<std::string> &out_file) {
if ( out_file.empty() )
throw BadOption("Output file name should not be empty");
} // checkOutFile
-void checkOutDir(const Option<std::string> &out_dir) {
- auto dir = opendir(out_dir.c_str());
+void checkInDir(const Option<std::string>& dir) {
+ auto stream = opendir(dir.c_str());
- if (dir) {
- closedir(dir);
- return;
- }
+ if (stream == NULL)
+ throw BadOption(std::string("Could not open directory: ") + std::strerror(errno) + ".");
- auto err = errno;
+ closedir(stream);
+} // checkInDir
- switch (err) {
- case ENOENT:
+void checkOutDir(const Option<std::string> &out_dir) {
+ auto stream = opendir(out_dir.c_str());
+
+ if (stream == NULL) {
+ // Do not consider the missing directory an error.
+ if (errno == ENOENT)
return;
- case ENOTDIR:
- throw BadOption("Output path is not directory");
- case EACCES:
- throw BadOption("Has no permission to open output directory");
- default:
- throw BadOption("Can not open output directory");
- }
-} // checkOutDir
-void checkDebugFile(const Option<std::string> &in_file) {
- if (access(in_file.c_str(), W_OK) != 0) {
- throw BadOption("Has no permission to open debug output file");
+ throw BadOption(std::string("Could not open directory: ") + std::strerror(errno) + ".");
}
-} // checkDebugFile
+
+ closedir(stream);
+} // checkOutDir
} // namespace cli
} // namespace ncc