From 9c92224e909efd12646c7d138daa05e851199ac6 Mon Sep 17 00:00:00 2001
From: NAUD Maxence <maxence.naud@cea.fr>
Date: Wed, 26 Feb 2025 12:39:06 +0000
Subject: [PATCH 1/3] fix 'ignoring attributes on template argument' message

---
 include/aidge/utils/FileManagement.hpp | 28 ++++++++++++++++++++++++++
 src/graph/GraphView.cpp                |  9 +++++----
 src/scheduler/Scheduler.cpp            |  9 +++++----
 3 files changed, 38 insertions(+), 8 deletions(-)
 create mode 100644 include/aidge/utils/FileManagement.hpp

diff --git a/include/aidge/utils/FileManagement.hpp b/include/aidge/utils/FileManagement.hpp
new file mode 100644
index 000000000..8158fbf19
--- /dev/null
+++ b/include/aidge/utils/FileManagement.hpp
@@ -0,0 +1,28 @@
+/********************************************************************************
+ * 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
+ *
+ ********************************************************************************/
+
+#include <cstdio>     // std::fclose, std::fopen
+#include <memory>
+#include <string>
+
+namespace Aidge {
+struct FileDeleter {
+    void operator()(FILE* fp) const {
+        if (fp) {
+            std::fclose(fp);
+        }
+    }
+};
+
+inline std::unique_ptr<FILE, FileDeleter> createFile(const std::string& fileName, const char* accessibility = "w") {
+    return std::unique_ptr<FILE, FileDeleter>(std::fopen(fileName.c_str(), accessibility));
+}
+}
diff --git a/src/graph/GraphView.cpp b/src/graph/GraphView.cpp
index 315844858..d0b539182 100644
--- a/src/graph/GraphView.cpp
+++ b/src/graph/GraphView.cpp
@@ -33,6 +33,7 @@
 #include "aidge/operator/Producer.hpp"
 #include "aidge/operator/Memorize.hpp"
 #include "aidge/utils/Directories.hpp"
+#include "aidge/utils/FileManagement.hpp"
 #include "aidge/utils/ErrorHandling.hpp"
 #include "aidge/utils/Types.h"
 
@@ -85,7 +86,7 @@ bool Aidge::GraphView::inView(const std::string& nodeName) const {
 }
 
 void Aidge::GraphView::save(const std::string& path, bool verbose, bool showProducers) const {
-    auto fp = std::unique_ptr<FILE, decltype(&std::fclose)>(std::fopen((path + ".mmd").c_str(), "w"), &std::fclose);
+    auto fp = createFile(path + ".mmd", "w");
 
     if (!fp) {
         AIDGE_THROW_OR_ABORT(std::runtime_error,
@@ -261,7 +262,7 @@ void Aidge::GraphView::logOutputs(const std::string& dirName) const {
 
     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);
+      auto fp = createFile(inputPath, "w");
       if (!fp) {
         AIDGE_THROW_OR_ABORT(std::runtime_error,
             "Could not create graph view log file: {}", inputPath);
@@ -1122,7 +1123,7 @@ void Aidge::GraphView::insertParent(NodePtr childNode,
  * | >1 node, 1 input    |     trivial      |      trivial      |     broadcast      |    broadcast       |
  * | 1 node, >1 inputs   |   (take first)   |   (take first)    |     same order     |       X            |
  * | >1 node, >1 inputs  |       X          |        X          |         X          |       X            |
- * 
+ *
  * Outputs conditions:
  * |  old    \     new   | 1 node, 1 output | >1 node, 1 output | 1 node, >1 outputs | >1 node, >1 outputs |
  * | ------------------- | ---------------- | ----------------- | ------------------ | ------------------- |
@@ -1130,7 +1131,7 @@ void Aidge::GraphView::insertParent(NodePtr childNode,
  * | >1 node, 1 output   |     trivial      |      trivial      |     take first     |       X             |
  * | 1 node, >1 outputs  |   (take first)   |   (take first)    |     same order     |       X             |
  * | >1 node, >1 outputs |       X          |        X          |         X          |       X             |
- * 
+ *
  * Only the X cases cannot possibly be resolved deterministically with sets of node.
  * These cases are therefore forbidden for the set-based `replace()` interface.
  * The remaining cases are handled by the GraphView-based `replace()` interface.
diff --git a/src/scheduler/Scheduler.cpp b/src/scheduler/Scheduler.cpp
index fabdc7ad2..eba195ad9 100644
--- a/src/scheduler/Scheduler.cpp
+++ b/src/scheduler/Scheduler.cpp
@@ -34,6 +34,7 @@
 #include "aidge/operator/OperatorTensor.hpp"
 #include "aidge/operator/Producer.hpp"
 #include "aidge/operator/Concat.hpp"
+#include "aidge/utils/FileManagement.hpp"
 #include "aidge/utils/Log.hpp"
 #include "aidge/utils/Types.h"
 
@@ -672,7 +673,7 @@ Aidge::MemoryManager Aidge::Scheduler::generateMemoryAutoConcat(bool incProducer
 
             std::shared_ptr<Node> concat = nullptr;
             // If the only child is a concatenation, check if we can allocate
-            // the concatenation result directly and skip allocation for this 
+            // the concatenation result directly and skip allocation for this
             // node output:
             if (childs.size() == 1 && (*childs.begin())->type() == Concat_Op::Type) {
                 concat = *childs.begin();
@@ -901,7 +902,7 @@ void Aidge::Scheduler::connectInputs(const std::vector<std::shared_ptr<Aidge::Te
 }
 
 void Aidge::Scheduler::saveSchedulingDiagram(const std::string& fileName) const {
-    auto fp = std::unique_ptr<FILE, decltype(&std::fclose)>(std::fopen((fileName + ".mmd").c_str(), "w"), &std::fclose);
+    auto fp = createFile(fileName + ".mmd", "w");
 
     if (!fp) {
         AIDGE_THROW_OR_ABORT(std::runtime_error,
@@ -931,7 +932,7 @@ void Aidge::Scheduler::saveSchedulingDiagram(const std::string& fileName) const
 }
 
 void Aidge::Scheduler::saveStaticSchedulingDiagram(const std::string& fileName) const {
-    auto fp = std::unique_ptr<FILE, decltype(&std::fclose)>(std::fopen((fileName + ".mmd").c_str(), "w"), &std::fclose);
+    auto fp = createFile(fileName + ".mmd", "w");
 
     if (!fp) {
         AIDGE_THROW_OR_ABORT(std::runtime_error,
@@ -966,7 +967,7 @@ void Aidge::Scheduler::saveStaticSchedulingDiagram(const std::string& fileName)
 }
 
 void Aidge::Scheduler::saveFactorizedStaticSchedulingDiagram(const std::string& fileName, size_t minRepeat) const {
-    auto fp = std::unique_ptr<FILE, decltype(&std::fclose)>(std::fopen((fileName + ".mmd").c_str(), "w"), &std::fclose);
+    auto fp = createFile(fileName + ".mmd", "w");
 
     if (!fp) {
         AIDGE_THROW_OR_ABORT(std::runtime_error,
-- 
GitLab


From 6e4671ef4af2a6c01a59bcaec92fe6c1f2bd2d04 Mon Sep 17 00:00:00 2001
From: NAUD Maxence <maxence.naud@cea.fr>
Date: Wed, 26 Feb 2025 12:40:38 +0000
Subject: [PATCH 2/3] fix 'possibly dangling reference to a temporary' message

---
 src/scheduler/MemoryManager.cpp | 2 +-
 src/scheduler/Scheduler.cpp     | 6 ++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/scheduler/MemoryManager.cpp b/src/scheduler/MemoryManager.cpp
index 05f461b82..8e35913f4 100644
--- a/src/scheduler/MemoryManager.cpp
+++ b/src/scheduler/MemoryManager.cpp
@@ -572,7 +572,7 @@ Aidge::MemoryManager::getPlanes(const std::shared_ptr<Node>& node) const
     const std::map<std::shared_ptr<Node>, std::vector<MemoryPlane> >
         ::const_iterator it = mMemPlanes.find(node);
 
-    if (it == mMemPlanes.end()) {
+    if (it == mMemPlanes.cend()) {
         AIDGE_THROW_OR_ABORT(std::runtime_error,
             "getSize(): no memory allocated for node name {}", node->name());
     }
diff --git a/src/scheduler/Scheduler.cpp b/src/scheduler/Scheduler.cpp
index eba195ad9..fa57f76db 100644
--- a/src/scheduler/Scheduler.cpp
+++ b/src/scheduler/Scheduler.cpp
@@ -591,7 +591,8 @@ Aidge::MemoryManager Aidge::Scheduler::generateMemory(bool incProducers, bool wr
                             node->name(), node->type());
 
                         const bool isWrappable = (requiredProtected.data < requiredData.data);
-                        const MemoryManager::MemoryPlane& memPlane = memManager.getPlanes(parent.first).end()[-parent.first->nbOutputs()+parent.second];
+                        const auto& memPlanes = memManager.getPlanes(parent.first);
+                        const MemoryManager::MemoryPlane& memPlane = memPlanes.at(memPlanes.size() - parent.first->nbOutputs() + parent.second); // use at() to avoid dangling reference pointer
 
                         if (isWrappable || !memManager.isWrapAround(
                                     memPlane.memSpace,
@@ -759,10 +760,11 @@ Aidge::MemoryManager Aidge::Scheduler::generateMemoryAutoConcat(bool incProducer
                                 node->name(), node->type());
 
                             const bool isWrappable = (requiredProtected.data < requiredData.data);
+                            const auto& memPlanes = memManager.getPlanes(parent.first);
                             const MemoryManager::MemoryPlane& memPlane
                                 = (concat && itConcat != concatMemPlane.end())
                                     ? itConcat->second
-                                    : memManager.getPlanes(parent.first).end()[-parent.first->nbOutputs()+parent.second];
+                                    : memPlanes.at(memPlanes.size()-parent.first->nbOutputs()+parent.second); // use at() to avoid dangling reference pointer
 
                             if (isWrappable || !memManager.isWrapAround(
                                         memPlane.memSpace,
-- 
GitLab


From 9a6798c42f4a6185512f73d7b13e6fcbd9a5d639 Mon Sep 17 00:00:00 2001
From: NAUD Maxence <maxence.naud@cea.fr>
Date: Wed, 26 Feb 2025 12:41:55 +0000
Subject: [PATCH 3/3] solve an inlining fail by removing inline

---
 include/aidge/graph/Node.hpp        | 9 +++------
 include/aidge/utils/Directories.hpp | 3 +--
 src/graph/Node.cpp                  | 6 ++++++
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/aidge/graph/Node.hpp b/include/aidge/graph/Node.hpp
index d71d095e7..9b16f76d5 100644
--- a/include/aidge/graph/Node.hpp
+++ b/include/aidge/graph/Node.hpp
@@ -213,10 +213,7 @@ public:
    * @param inID
    * @return std::pair<std::shared_ptr<Node>, IOIndex_t>
    */
-  inline std::pair<NodePtr, IOIndex_t> input(const IOIndex_t inID) const {
-    AIDGE_ASSERT((inID != gk_IODefaultIndex) && (inID < nbInputs()), "Input index out of bound.");
-    return std::pair<NodePtr, IOIndex_t>(mParents[inID], mIdOutParents[inID]);
-  }
+  std::pair<std::shared_ptr<Node>, IOIndex_t> input(const IOIndex_t inID) const;
 
 
   /**
@@ -328,7 +325,7 @@ public:
    * Default to 0.
    * @param otherInId ID of the other Node input to connect to the current Node.
    * Default to the first available data input.
-   * 
+   *
    * @note otherNode shared_ptr is passed by refenrece in order to be able to detect
    * possible dangling connection situations in debug using ref counting.
    */
@@ -509,7 +506,7 @@ private:
    * @param otherNode
    * @param outId
    * @param otherInId
-   * 
+   *
    * @note otherNode shared_ptr is passed by refenrece in order to be able to detect
    * possible dangling connection situations in debug using ref counting.
    */
diff --git a/include/aidge/utils/Directories.hpp b/include/aidge/utils/Directories.hpp
index 783783946..c42280a6d 100644
--- a/include/aidge/utils/Directories.hpp
+++ b/include/aidge/utils/Directories.hpp
@@ -11,11 +11,10 @@
 #ifndef AIDGE_DIRECTORIES_H_
 #define AIDGE_DIRECTORIES_H_
 
-#include <algorithm>
+#include <algorithm>  // std::replace_if
 #include <errno.h>
 #include <string>
 // #include <string_view> available in c++-17
-#include <vector>
 
 #include <fmt/core.h>
 #include <fmt/format.h>
diff --git a/src/graph/Node.cpp b/src/graph/Node.cpp
index 1c8585d1d..0dec30c2f 100644
--- a/src/graph/Node.cpp
+++ b/src/graph/Node.cpp
@@ -173,6 +173,12 @@ std::vector<std::pair<std::shared_ptr<Aidge::Node>, Aidge::IOIndex_t>> Aidge::No
     return res;
 }
 
+std::pair<std::shared_ptr<Aidge::Node>, Aidge::IOIndex_t> Aidge::Node::input(const Aidge::IOIndex_t inID) const {
+    // nbInputs already < gk_IODefaultIndex
+    AIDGE_ASSERT((inID < nbInputs()), "Input index out of bound.");
+    return std::pair<NodePtr, IOIndex_t>(mParents[inID], mIdOutParents[inID]);
+}
+
 // void Aidge::Node::setInput(const Aidge::IOIndex_t idx, const std::shared_ptr<Aidge::Tensor>
 // tensor) {
 //     assert(((idx != gk_IODefaultIndex) && (idx < nbInputs())) && "Parent index out of bound.");
-- 
GitLab