diff --git a/include/aidge/graph/GraphView.hpp b/include/aidge/graph/GraphView.hpp
index 1f29ffbbf76e706de2e27400d0bdef73c945181b..9dccb5440e0b9dc1d102798322656791e5f845fd 100644
--- a/include/aidge/graph/GraphView.hpp
+++ b/include/aidge/graph/GraphView.hpp
@@ -119,7 +119,9 @@ public:
     inline std::set<NodePtr> inputNodes() const noexcept {
         std::set<NodePtr> nodes;
         for (auto node : mInputNodes) {
-            nodes.insert(node.first);
+            if (node.first != nullptr) {
+                nodes.insert(node.first);
+            }
         }
         return nodes;
     }
@@ -127,7 +129,9 @@ public:
     inline std::set<NodePtr> outputNodes() const noexcept {
         std::set<NodePtr> nodes;
         for (auto node : mOutputNodes) {
-            nodes.insert(node.first);
+            if (node.first != nullptr) {
+                nodes.insert(node.first);
+            }
         }
         return nodes;
     }
diff --git a/src/graph/GraphView.cpp b/src/graph/GraphView.cpp
index 232e8f5e9b9ecf789e43c63c1f215cb728cbeb68..3ccc1174db40e161641b98dd906a69fdc4ecee3c 100644
--- a/src/graph/GraphView.cpp
+++ b/src/graph/GraphView.cpp
@@ -130,23 +130,33 @@ void Aidge::GraphView::save(std::string path, bool verbose, bool showProducers)
 
     size_t inputIdx = 0;
     for (auto input : mInputNodes) {
-      std::fprintf(fp, "input%lu((in#%lu)):::inputCls--->|&rarr;%u|%s_%s\n", inputIdx, inputIdx,
-                  input.second, input.first->type().c_str(), namePtrTable[input.first].c_str());
+      if (input.first != nullptr) {
+        std::fprintf(fp, "input%lu((in#%lu)):::inputCls--->|&rarr;%u|%s_%s\n", inputIdx, inputIdx,
+                    input.second, input.first->type().c_str(), namePtrTable[input.first].c_str());
+      }
+      else {
+        std::fprintf(fp, "input%lu((in#%lu)):::inputCls\n", inputIdx, inputIdx);
+      }
       ++inputIdx;
     }
 
     size_t outputIdx = 0;
     for (auto output : mOutputNodes) {
-      // Add-on to display the operator's output dimensions
-      std::string dims = "";
-      const auto op = std::dynamic_pointer_cast<OperatorTensor>(output.first->getOperator());
-      if (op && !op->getOutput(output.second)->dims().empty()) {
-        dims += " " + fmt::format("{}", op->getOutput(output.second)->dims());
-      }
+      if (output.first != nullptr) {
+        // Add-on to display the operator's output dimensions
+        std::string dims = "";
+        const auto op = std::dynamic_pointer_cast<OperatorTensor>(output.first->getOperator());
+        if (op && !op->getOutput(output.second)->dims().empty()) {
+          dims += " " + fmt::format("{}", op->getOutput(output.second)->dims());
+        }
 
-      std::fprintf(fp, "%s_%s--->|\"%u%s&rarr;\"|output%lu((out#%lu)):::outputCls\n",
-                   output.first->type().c_str(), namePtrTable[output.first].c_str(), output.second,
-                   dims.c_str(), outputIdx, outputIdx);
+        std::fprintf(fp, "%s_%s--->|\"%u%s&rarr;\"|output%lu((out#%lu)):::outputCls\n",
+                    output.first->type().c_str(), namePtrTable[output.first].c_str(), output.second,
+                    dims.c_str(), outputIdx, outputIdx);
+      }
+      else {
+        std::fprintf(fp, "output%lu((out#%lu)):::outputCls\n", outputIdx, outputIdx);
+      }
       ++outputIdx;
     }
 
@@ -164,29 +174,43 @@ void Aidge::GraphView::save(std::string path, bool verbose, bool showProducers)
 ///////////////////////////////////////////////////////
 
 void Aidge::GraphView::setOrderedInputs(const std::vector<std::pair<NodePtr, IOIndex_t>>& inputs) {
-  AIDGE_ASSERT(inputs.size() <= mInputNodes.size(), "too many specified number of inputs");
-
+  size_t nbInputs = 0;
   std::vector<std::pair<NodePtr, IOIndex_t>> ignoredInputs(mInputNodes);
   for (auto input : inputs) {
-    auto it = std::find(ignoredInputs.begin(), ignoredInputs.end(), input);
-    AIDGE_ASSERT(it != ignoredInputs.end(), "unknown or duplicate input");
-    ignoredInputs.erase(it);
+    // Allow to specify dummy inputs (nullptr), but this will only be reflected
+    // in mInputNodes. All other functions (nbInputs(), inputs()) will not take
+    // it into account.
+    if (input.first != nullptr) {
+      auto it = std::find(ignoredInputs.begin(), ignoredInputs.end(), input);
+      AIDGE_ASSERT(it != ignoredInputs.end(), "unknown or duplicate input");
+      ignoredInputs.erase(it);
+      ++nbInputs;
+    }
   }
 
+  AIDGE_ASSERT(nbInputs <= mInputNodes.size(), "too many specified number of inputs");
+
   mInputNodes = inputs;
   mInputNodes.insert(mInputNodes.end(), ignoredInputs.begin(), ignoredInputs.end());
 }
 
 void Aidge::GraphView::setOrderedOutputs(const std::vector<std::pair<NodePtr, IOIndex_t>>& outputs) {
-  AIDGE_ASSERT(outputs.size() <= mOutputNodes.size(), "too many specified number of outputs");
-
+  size_t nbOutputs = 0;
   std::vector<std::pair<NodePtr, IOIndex_t>> ignoredOutputs(mOutputNodes);
   for (auto output : outputs) {
-    auto it = std::find(ignoredOutputs.begin(), ignoredOutputs.end(), output);
-    AIDGE_ASSERT(it != ignoredOutputs.end(), "unknown or duplicate output");
-    ignoredOutputs.erase(it);
+    // Allow to specify dummy outputs (nullptr), but this will only be reflected
+    // in mOutputNodes. All other functions (nbOutputs(), outputs()) will not take
+    // it into account.
+    if (output.first != nullptr) {
+      auto it = std::find(ignoredOutputs.begin(), ignoredOutputs.end(), output);
+      AIDGE_ASSERT(it != ignoredOutputs.end(), "unknown or duplicate output");
+      ignoredOutputs.erase(it);
+      ++nbOutputs;
+    }
   }
 
+  AIDGE_ASSERT(nbOutputs <= mOutputNodes.size(), "too many specified number of outputs");
+
   mOutputNodes = outputs;
   mOutputNodes.insert(mOutputNodes.end(), ignoredOutputs.begin(), ignoredOutputs.end());
 }
diff --git a/src/scheduler/Scheduler.cpp b/src/scheduler/Scheduler.cpp
index fcff5b8f43440229636bc65be8100d706a74d177..16d2104ba1f1ceda4b65c1f6901f3ebc29cf8c99 100644
--- a/src/scheduler/Scheduler.cpp
+++ b/src/scheduler/Scheduler.cpp
@@ -369,7 +369,10 @@ Aidge::NbElts_t Aidge::SequentialScheduler::getNbAvailableData(const std::shared
                     return upperInput.first->getOperator()->getNbProducedData(upperInput.second);
                 } 
             }
-            ++nodeInputIdx;
+            else if (input.first != nullptr) {
+                // Do not take into account dummy inputs from getOrderedInputs()
+                ++nodeInputIdx;
+            }
         }
     }