diff --git a/agui2/src/Execution/ParallelExecutor.cpp b/agui2/src/Execution/ParallelExecutor.cpp index b8dd613d388a9360f0c458467396a0c1bf73287b..f582690b9a0c3dae5c7ff32388f73d33772ce7fd 100644 --- a/agui2/src/Execution/ParallelExecutor.cpp +++ b/agui2/src/Execution/ParallelExecutor.cpp @@ -10,13 +10,12 @@ #include <Models/OutputModelBox.hpp> #include <exception/CommonException.h> -Q_GLOBAL_STATIC(ParallelExecutor, parallelExecutorInstance); - std::shared_ptr<abstraction::OperationAbstraction> ParallelExecutor::execute(OutputModelBox* output) { - for (auto* box: this->modelBoxes) { + for (auto* box: ModelBox::getAllModelBoxes()) { box->id = static_cast<size_t>(-1); box->level = static_cast<size_t>(-1); + box->clearCachedResult(); } // collect all boxes leading to the output box @@ -165,22 +164,9 @@ std::shared_ptr<abstraction::OperationAbstraction> ParallelExecutor::execute(Out std::vector<std::future<void>> futures; for (auto* box: level) { - futures.push_back(std::async(std::launch::async, [=]{ box->run(); })); + futures.push_back(std::async(std::launch::async, [=]{ box->getCachedResultOrEvaluate(); })); } } - return output->getResult(); -} - -ParallelExecutor* ParallelExecutor::getInstance() { - return parallelExecutorInstance; -} - -void ParallelExecutor::addModelBox(ModelBox* modelBox) { - this->modelBoxes.push_back(modelBox); -} - -void ParallelExecutor::removeModelBox(ModelBox* modelBox) { - auto& bs = this->modelBoxes; - bs.erase(std::remove(bs.begin(), bs.end(), modelBox), bs.end()); -} + return output->getCachedResult(); +} \ No newline at end of file diff --git a/agui2/src/Execution/ParallelExecutor.hpp b/agui2/src/Execution/ParallelExecutor.hpp index fe4418606fffa32962bd36c31593939d4329975b..d3cc2e43156b4a49ed4b9e430c4911434b7f57e4 100644 --- a/agui2/src/Execution/ParallelExecutor.hpp +++ b/agui2/src/Execution/ParallelExecutor.hpp @@ -7,16 +7,7 @@ class ParallelExecutor { public: - - std::shared_ptr<abstraction::OperationAbstraction> execute(OutputModelBox* output); - - void addModelBox(ModelBox* modelBox); - void removeModelBox(ModelBox* modelBox); - - static ParallelExecutor* getInstance(); - -private: - std::vector<ModelBox*> modelBoxes; + static std::shared_ptr<abstraction::OperationAbstraction> execute(OutputModelBox* output); }; diff --git a/agui2/src/MainWindow.cpp b/agui2/src/MainWindow.cpp index 53c956c88a4bd6bea63043a1a48e9e84859c728d..3897d6c69c1490af913a444750771258c56f6772 100644 --- a/agui2/src/MainWindow.cpp +++ b/agui2/src/MainWindow.cpp @@ -58,10 +58,10 @@ void MainWindow::on_RunBtn_clicked() std::shared_ptr<abstraction::OperationAbstraction> result; try { #if 0 - this->outputBox->getModelBox()->clearResultRecursive(); + ModelBox::clearCachedResults(); result = this->outputBox->getModelBox()->run(); #else - result = ParallelExecutor::getInstance()->execute(dynamic_cast<OutputModelBox*>(this->outputBox->getModelBox())); + result = ParallelExecutor::execute(dynamic_cast<OutputModelBox*>(this->outputBox->getModelBox())); #endif } catch (const exception::CommonException& e) { diff --git a/agui2/src/Models/AlgorithmModelBox.cpp b/agui2/src/Models/AlgorithmModelBox.cpp index 261ad6a481a1467a66867002ea13237f8b1e5a90..ac16d04ddb4d3966f892260df24f1da32f7a6d66 100644 --- a/agui2/src/Models/AlgorithmModelBox.cpp +++ b/agui2/src/Models/AlgorithmModelBox.cpp @@ -10,17 +10,18 @@ AlgorithmModelBox::AlgorithmModelBox(Algorithm* algorithm) : ModelBox(ModelType::Algorithm, algorithm->getInputCount()) , algorithm(algorithm) {} -std::shared_ptr<abstraction::OperationAbstraction> AlgorithmModelBox::runInternal() { +std::shared_ptr<abstraction::OperationAbstraction> AlgorithmModelBox::evaluate() { std::vector<std::shared_ptr<abstraction::OperationAbstraction>> params; for (auto* input: this->inputs) { if (!input) return nullptr; - params.push_back(input->run()); + params.push_back(input->getCachedResultOrEvaluate()); if (!params.back()) return nullptr; } - return this->algorithm->execute(params); + this->result = this->algorithm->execute(params); + return this->result; } std::string AlgorithmModelBox::getName() const { diff --git a/agui2/src/Models/AlgorithmModelBox.hpp b/agui2/src/Models/AlgorithmModelBox.hpp index 6aa0293628917c25af5eb40f35a07fc6af0c330d..d42b462a34f8d8cb1c372424693bdfa9db5788c8 100644 --- a/agui2/src/Models/AlgorithmModelBox.hpp +++ b/agui2/src/Models/AlgorithmModelBox.hpp @@ -9,8 +9,7 @@ public: std::string getName() const override; Algorithm* getAlgorithm() const { return this->algorithm; } -protected: - std::shared_ptr<abstraction::OperationAbstraction> runInternal() override; + std::shared_ptr<abstraction::OperationAbstraction> evaluate() override; private: Algorithm* algorithm; diff --git a/agui2/src/Models/InputModelBox.cpp b/agui2/src/Models/InputModelBox.cpp index 0456e740c80680b0dd60e5a823b68b39274049ed..c1fd66ba8a468162015a9ea0e4de6626632db201 100644 --- a/agui2/src/Models/InputModelBox.cpp +++ b/agui2/src/Models/InputModelBox.cpp @@ -4,7 +4,7 @@ InputModelBox::InputModelBox() : ModelBox(ModelType::Input, 0) {} -std::shared_ptr<abstraction::OperationAbstraction> InputModelBox::runInternal() { +std::shared_ptr<abstraction::OperationAbstraction> InputModelBox::evaluate() { return this->result; } diff --git a/agui2/src/Models/InputModelBox.hpp b/agui2/src/Models/InputModelBox.hpp index 8e4a01105fde3260d5c01b0dc0db50a30632b53b..9347b7ba1e5fdd6bd6e418f9c7e5a0a5b2eb0392 100644 --- a/agui2/src/Models/InputModelBox.hpp +++ b/agui2/src/Models/InputModelBox.hpp @@ -6,9 +6,9 @@ class InputModelBox : public ModelBox { public: explicit InputModelBox(); - void clearResultRecursive() override {} + void clearCachedResult() override {} - std::shared_ptr<abstraction::OperationAbstraction> runInternal() override; + std::shared_ptr<abstraction::OperationAbstraction> evaluate() override; std::string getName() const override; diff --git a/agui2/src/Models/ModelBox.cpp b/agui2/src/Models/ModelBox.cpp index 89ef621d549504b9d2c454a23e6c3f3e9f43a735..5658dff5649cc3f70d135bce39de4e7084b5547d 100644 --- a/agui2/src/Models/ModelBox.cpp +++ b/agui2/src/Models/ModelBox.cpp @@ -6,6 +6,8 @@ #include <Execution/ParallelExecutor.hpp> +std::vector<ModelBox*> ModelBox::allModelBoxes; + ModelBox::ModelBox(ModelType type, uint8_t maxInputCount) : type(type) , maxInputCount(maxInputCount) @@ -13,11 +15,12 @@ ModelBox::ModelBox(ModelType type, uint8_t maxInputCount) { // Input box cannot have inputs, other boxes must have inputs Q_ASSERT((this->type == ModelType::Input) == (this->maxInputCount == 0)); - ParallelExecutor::getInstance()->addModelBox(this); + ModelBox::allModelBoxes.push_back(this); } ModelBox::~ModelBox() { - ParallelExecutor::getInstance()->removeModelBox(this); + auto& bs = ModelBox::allModelBoxes; + bs.erase(std::remove(bs.begin(), bs.end(), this), bs.end()); } void ModelBox::setInput(uint8_t slot, ModelBox* model) { @@ -35,17 +38,14 @@ void ModelBox::removeOutput(ModelBox* model, uint8_t slot) { this->outputs.erase({model, slot}); } -std::shared_ptr<abstraction::OperationAbstraction> ModelBox::run() { - if (!this->result) - this->result = this->runInternal(); - - return this->result; +std::shared_ptr<abstraction::OperationAbstraction> ModelBox::getCachedResultOrEvaluate() { + if (this->result) + return this->result; + return this->evaluate(); } -void ModelBox::clearResultRecursive() { - this->result.reset(); - for (auto* input: this->inputs) { - input->clearResultRecursive(); +void ModelBox::clearCachedResults() { + for (auto* box: ModelBox::allModelBoxes) { + box->clearCachedResult(); } - } diff --git a/agui2/src/Models/ModelBox.hpp b/agui2/src/Models/ModelBox.hpp index 747c27d97072096df4117ee50b543ba5584c014e..8af9450d2b8e6a40097e91cbdfa7e258815d9eb3 100644 --- a/agui2/src/Models/ModelBox.hpp +++ b/agui2/src/Models/ModelBox.hpp @@ -33,14 +33,15 @@ public: uint8_t getMaxInputCount() const { return this->maxInputCount; } virtual bool canHaveOutput() const { return true; } - std::shared_ptr<abstraction::OperationAbstraction> getResult() const { return this->result; } - virtual void clearResultRecursive(); + std::shared_ptr<abstraction::OperationAbstraction> getCachedResult() const { return this->result; } + std::shared_ptr<abstraction::OperationAbstraction> getCachedResultOrEvaluate(); + virtual void clearCachedResult() { this->result.reset(); } + virtual std::shared_ptr<abstraction::OperationAbstraction> evaluate() = 0; - std::shared_ptr<abstraction::OperationAbstraction> run(); + static const std::vector<ModelBox*>& getAllModelBoxes() { return ModelBox::allModelBoxes; } + static void clearCachedResults(); protected: - virtual std::shared_ptr<abstraction::OperationAbstraction> runInternal() = 0; - ModelType type; uint8_t maxInputCount = 0; @@ -51,6 +52,8 @@ protected: GraphicsBox* graphicsBox = nullptr; private: + static std::vector<ModelBox*> allModelBoxes; + // for topological sorting in ParallelExecutor mutable size_t id = static_cast<size_t>(-1); mutable size_t level = static_cast<size_t>(-1); diff --git a/agui2/src/Models/OutputModelBox.cpp b/agui2/src/Models/OutputModelBox.cpp index b7a54af9f471ae0a608f7d264d6c86f800444813..13c2e21fc9f4e2404f5c8207b749e4c8720dad36 100644 --- a/agui2/src/Models/OutputModelBox.cpp +++ b/agui2/src/Models/OutputModelBox.cpp @@ -6,11 +6,11 @@ OutputModelBox::OutputModelBox() : ModelBox(ModelType::Output, 1) {} -std::shared_ptr<abstraction::OperationAbstraction> OutputModelBox::runInternal() { +std::shared_ptr<abstraction::OperationAbstraction> OutputModelBox::evaluate() { assert(this->inputs.size() == 1); if (!this->inputs[0]) return nullptr; - return inputs[0]->run(); + return inputs[0]->getCachedResultOrEvaluate(); } std::string OutputModelBox::getName() const { diff --git a/agui2/src/Models/OutputModelBox.hpp b/agui2/src/Models/OutputModelBox.hpp index 3bfb8545b20d6c33077e163cdfcd835a6d8a77e1..03e630a2c23c8b398e3bf67fa3bf77f100e93746 100644 --- a/agui2/src/Models/OutputModelBox.hpp +++ b/agui2/src/Models/OutputModelBox.hpp @@ -9,7 +9,7 @@ public: bool canHaveOutput() const override { return false; } - std::shared_ptr<abstraction::OperationAbstraction> runInternal() override; + std::shared_ptr<abstraction::OperationAbstraction> evaluate() override; };