From 89a6dced20ee2a3b1a3e4f03d79c36ea9b283071 Mon Sep 17 00:00:00 2001 From: cmoineau <cyril.moineau@cea.fr> Date: Thu, 14 Mar 2024 13:48:34 +0000 Subject: [PATCH] Add logOutputs method in graphView. --- include/aidge/data/Data.hpp | 3 +- include/aidge/data/Tensor.hpp | 2 +- include/aidge/graph/GraphView.hpp | 4 +- include/aidge/utils/Directories.hpp | 83 +++++++++++++++++++++++ python_binding/data/pybind_Data.cpp | 4 +- python_binding/graph/pybind_GraphView.cpp | 2 +- src/graph/GraphView.cpp | 26 ++++++- 7 files changed, 117 insertions(+), 7 deletions(-) create mode 100644 include/aidge/utils/Directories.hpp diff --git a/include/aidge/data/Data.hpp b/include/aidge/data/Data.hpp index d8412dbd4..47ce3514d 100644 --- a/include/aidge/data/Data.hpp +++ b/include/aidge/data/Data.hpp @@ -52,6 +52,7 @@ public: return mType; } virtual ~Data() = default; + virtual std::string toString() const; private: const std::string mType; @@ -84,4 +85,4 @@ namespace Aidge { inline auto format_as(DataType dt) { return EnumStrings<Aidge::DataType>::data[static_cast<int>(dt)]; } } -#endif /* AIDGE_DATA_H_ */ \ No newline at end of file +#endif /* AIDGE_DATA_H_ */ diff --git a/include/aidge/data/Tensor.hpp b/include/aidge/data/Tensor.hpp index b82ec89d0..1f9c5a5ec 100644 --- a/include/aidge/data/Tensor.hpp +++ b/include/aidge/data/Tensor.hpp @@ -445,7 +445,7 @@ public: set<expectedType>(getStorageIdx(coordIdx), value); } - std::string toString() const; + std::string toString() const override; inline void print() const { fmt::print("{}\n", toString()); } diff --git a/include/aidge/graph/GraphView.hpp b/include/aidge/graph/GraphView.hpp index 46fa56ef0..0c6b7f033 100644 --- a/include/aidge/graph/GraphView.hpp +++ b/include/aidge/graph/GraphView.hpp @@ -98,6 +98,8 @@ public: */ void save(const std::string& path, bool verbose = false, bool showProducers = true) const; + void logOutputs(const std::string& dirName) const; + /** * Check that a node is in the current GraphView. * @param nodePtr Node to check @@ -283,7 +285,7 @@ public: * added to the list, and so on. * - Any remaining nodes have no path to the root node and are added in * arbitrary order. In this case, the ranking is not garanteed to be unique. - * + * * If the ranking cannot be garanteed to be unique, the second item indicates * the rank from which unicity cannot be garanteed. * @return std::pair<std::vector<NodePtr>, size_t> Pair with the list of ranked diff --git a/include/aidge/utils/Directories.hpp b/include/aidge/utils/Directories.hpp new file mode 100644 index 000000000..3bc07b9dd --- /dev/null +++ b/include/aidge/utils/Directories.hpp @@ -0,0 +1,83 @@ +/******************************************************************************** + * Copyright (c) 2023 CEA-List + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + ********************************************************************************/ + + +#ifndef AIDGE_DIRECTORIES_H_ +#define AIDGE_DIRECTORIES_H_ + + +#include <string> // std::string +#include <sstream> // std::stringstream +#include <iostream> +#include <sys/stat.h> +#include <errno.h> + +#ifdef WIN32 +#include <direct.h> +#else +#include <sys/types.h> +#include <unistd.h> +#endif + +namespace Aidge { + + bool isNotValidFilePath(int c) { + return (iscntrl(c) + || c == '<' + || c == '>' + || c == ':' + || c == '"' + || c == '|' + || c == '?' + || c == '*'); + } + + std::string filePath(const std::string& str) { + std::string filePath(str); + std::replace_if(filePath.begin(), filePath.end(), + isNotValidFilePath, '_'); + return filePath; + } + + + bool createDirectories(const std::string& dirName) + { + std::stringstream path(dirName); + std::string dir; + std::string pathToDir(""); + int status = 0; + + while (std::getline(path, dir, '/') && status == 0) { + pathToDir += dir + '/'; + struct stat fileStat; + if (stat(pathToDir.c_str(), &fileStat) != 0) { + // Directory does not exist + #ifdef WIN32 + status = _mkdir(pathToDir.c_str()); + #else + #if defined(S_IRWXU) + status = mkdir(pathToDir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); + #else + status = mkdir(pathToDir.c_str()); + #endif + #endif + } else if (!S_ISDIR(fileStat.st_mode)) { + status = -1; + } + } + return (status == 0 || errno == EEXIST); + } + + +} + +#endif //AIDGE_DIRECTORIES_H_ + diff --git a/python_binding/data/pybind_Data.cpp b/python_binding/data/pybind_Data.cpp index df3792fd7..724b10f87 100644 --- a/python_binding/data/pybind_Data.cpp +++ b/python_binding/data/pybind_Data.cpp @@ -26,12 +26,12 @@ void init_Data(py::module& m){ .value("Int64", DataType::Int64) .value("UInt8", DataType::UInt8) .value("UInt32", DataType::UInt32) - .value("UInt64", DataType::UInt64) + .value("UInt64", DataType::UInt64) ; py::class_<Data, std::shared_ptr<Data>>(m,"Data") .def(py::init<const std::string&>()); - + } } diff --git a/python_binding/graph/pybind_GraphView.cpp b/python_binding/graph/pybind_GraphView.cpp index a41d0d928..eae05d8e2 100644 --- a/python_binding/graph/pybind_GraphView.cpp +++ b/python_binding/graph/pybind_GraphView.cpp @@ -30,7 +30,7 @@ void init_GraphView(py::module& m) { :param path: save location :type path: str )mydelimiter") - + .def("log_outputs", &GraphView::logOutputs, py::arg("path")) .def("get_output_nodes", &GraphView::outputNodes, R"mydelimiter( Get set of output Nodes. diff --git a/src/graph/GraphView.cpp b/src/graph/GraphView.cpp index 005a7e679..edcea9544 100644 --- a/src/graph/GraphView.cpp +++ b/src/graph/GraphView.cpp @@ -26,6 +26,7 @@ #include "aidge/operator/GenericOperator.hpp" #include "aidge/operator/MetaOperator.hpp" #include "aidge/utils/ErrorHandling.hpp" +#include "aidge/utils/Directories.hpp" /////////////////////////////////////////////////////// // FUNCTIONAL DESCRIPTION @@ -193,6 +194,29 @@ void Aidge::GraphView::save(const std::string& path, bool verbose, bool showProd fmt::print(fp.get(), "\n"); } +void Aidge::GraphView::logOutputs(const std::string& dirName) const { + if (!Aidge::createDirectories(dirName)){ + AIDGE_THROW_OR_ABORT(std::runtime_error, "Failed to create directory: {}.", dirName); + } + for (std::shared_ptr<Node> nodePtr : getNodes()) { + + const std::string& nodePath = dirName + "/" + Aidge::filePath(nodePtr->name()) +"/"; + if (!Aidge::createDirectories(nodePath)){ + AIDGE_THROW_OR_ABORT(std::runtime_error, "Failed to create directory: {}.", nodePath); + } + + for (IOIndex_t outIdx = 0; outIdx < nodePtr->nbOutputs(); ++outIdx) { + const std::string& inputPath = nodePath +"output_" + std::to_string(outIdx) + ".log"; + auto fp = std::unique_ptr<FILE, decltype(&std::fclose)>(std::fopen(inputPath.c_str(), "w"), &std::fclose); + if (!fp) { + AIDGE_THROW_OR_ABORT(std::runtime_error, + "Could not create graph view log file: {}", inputPath); + } + fmt::print(fp.get(), "{}\n", nodePtr->getOperator()->getRawOutput(outIdx)->toString().c_str()); + } + } +} + void Aidge::GraphView::setRootNode(NodePtr node) { AIDGE_ASSERT(mNodes.find(node) != mNodes.end(), "Root node is not in the GraphView!"); mRootNode = node; @@ -356,7 +380,7 @@ void Aidge::GraphView::forwardDims(const std::vector<std::vector<Aidge::DimSize_ } } else { AIDGE_ASSERT(nodePtr->getOperator()->getRawInput(i) - && !std::static_pointer_cast<Tensor>(nodePtr->getOperator()->getRawInput(i))->empty(), + && !std::static_pointer_cast<Tensor>(nodePtr->getOperator()->getRawInput(i))->empty(), "Missing input#{} for node {} ({})", i, nodePtr->name(), nodePtr->type()); } -- GitLab