Skip to content

Commit

Permalink
Use std::vector instead of std::set for insertion-ordered execution o…
Browse files Browse the repository at this point in the history
…f host functions

Closes #707
  • Loading branch information
ptheywood committed Oct 7, 2021
1 parent 2e00459 commit f419323
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 47 deletions.
54 changes: 27 additions & 27 deletions include/flamegpu/model/ModelData.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <list>
#include <memory>
#include <typeindex>
#include <set>
#include <vector>
#include <string>

#include "flamegpu/model/EnvironmentDescription.h"
Expand Down Expand Up @@ -61,35 +61,35 @@ struct ModelData : std::enable_shared_from_this<ModelData>{
*/
typedef std::list<std::shared_ptr<LayerData>> LayerList;
/**
* Set of Init function pointers
* set<FLAMEGPU_INIT_FUNCTION_POINTER>
* Vector of Init function pointers.
* Uses a vector rather than a set to preserve order.
*/
typedef std::set<FLAMEGPU_INIT_FUNCTION_POINTER> InitFunctionSet;
typedef std::vector<FLAMEGPU_INIT_FUNCTION_POINTER> InitFunctionVector;
/**
* Set of Step function pointers
* set<FLAMEGPU_STEP_FUNCTION_POINTER>
* Vector of Step function pointers.
* Uses a vector rather than a set to preserve order.
*/
typedef std::set<FLAMEGPU_STEP_FUNCTION_POINTER> StepFunctionSet;
typedef std::vector<FLAMEGPU_STEP_FUNCTION_POINTER> StepFunctionVector;
/**
* Set of Step function callback pointers
* set<HostFunctionCallback>
* Vector of Step function callback pointers.
* Uses a vector rather than a set to preserve order.
*/
typedef std::set<HostFunctionCallback*> HostFunctionCallbackSet;
typedef std::vector<HostFunctionCallback*> HostFunctionCallbackVector;
/**
* Set of host condition callback pointers
* set<HostFunctionConditionCallback>
* Vector of host condition callback pointers.
* Uses a vector rather than a set to preserve order.
*/
typedef std::set<HostFunctionConditionCallback*> HostFunctionConditionCallbackSet;
typedef std::vector<HostFunctionConditionCallback*> HostFunctionConditionCallbackVector;
/**
* Set of Exit function pointers
* set<FLAMEGPU_EXIT_FUNCTION_POINTER>
* Vector of Exit function pointers.
* Uses a vector rather than a set to preserve order.
*/
typedef std::set<FLAMEGPU_EXIT_FUNCTION_POINTER> ExitFunctionSet;
typedef std::vector<FLAMEGPU_EXIT_FUNCTION_POINTER> ExitFunctionVector;
/**
* Set of Exit condition pointers
* set<FLAMEGPU_EXIT_CONDITION_POINTER>
* Vector of Exit condition pointers.
* Uses a vector rather than a set to preserve order.
*/
typedef std::set<FLAMEGPU_EXIT_CONDITION_POINTER> ExitConditionSet;
typedef std::vector<FLAMEGPU_EXIT_CONDITION_POINTER> ExitConditionVector;

/**
* Holds all of the model's agent definitions
Expand All @@ -110,23 +110,23 @@ struct ModelData : std::enable_shared_from_this<ModelData>{
/**
* Holds pointers to all of the init functions used by the model
*/
InitFunctionSet initFunctions;
HostFunctionCallbackSet initFunctionCallbacks;
InitFunctionVector initFunctions;
HostFunctionCallbackVector initFunctionCallbacks;
/**
* Holds pointers to all of the step functions used by the model
*/
StepFunctionSet stepFunctions;
HostFunctionCallbackSet stepFunctionCallbacks;
StepFunctionVector stepFunctions;
HostFunctionCallbackVector stepFunctionCallbacks;
/**
* Holds pointers to all of the exit functions used by the model
*/
ExitFunctionSet exitFunctions;
HostFunctionCallbackSet exitFunctionCallbacks;
ExitFunctionVector exitFunctions;
HostFunctionCallbackVector exitFunctionCallbacks;
/**
* Holds pointers to all of the exit conditions used by the model
*/
ExitConditionSet exitConditions;
HostFunctionConditionCallbackSet exitConditionCallbacks;
ExitConditionVector exitConditions;
HostFunctionConditionCallbackVector exitConditionCallbacks;
/**
* Holds all of the model's environment property definitions
*/
Expand Down
20 changes: 12 additions & 8 deletions include/flamegpu/model/ModelDescription.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,28 +385,32 @@ class ModelDescription {

#ifdef SWIG
void ModelDescription::addInitFunctionCallback(HostFunctionCallback* func_callback) {
if (!model->initFunctionCallbacks.insert(func_callback).second) {
if (std::find(model->initFunctionCallbacks.begin(), model->initFunctionCallbacks.end(), func_callback) != model->initFunctionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same init function callback twice,"
"in ModelDescription::addInitFunctionCallback()");
}
}
model->initFunctionCallbacks.push_back(func_callback);
}
void ModelDescription::addStepFunctionCallback(HostFunctionCallback* func_callback) {
if (!model->stepFunctionCallbacks.insert(func_callback).second) {
if (std::find(model->stepFunctionCallbacks.begin(), model->stepFunctionCallbacks.end(), func_callback) != model->stepFunctionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same step function callback twice,"
"in ModelDescription::addStepFunctionCallback()");
}
}
model->stepFunctionCallbacks.push_back(func_callback);
}
void ModelDescription::addExitFunctionCallback(HostFunctionCallback* func_callback) {
if (!model->exitFunctionCallbacks.insert(func_callback).second) {
if (std::find(model->exitFunctionCallbacks.begin(), model->exitFunctionCallbacks.end(), func_callback) != model->exitFunctionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same exit function callback twice,"
"in ModelDescription::addExitFunctionCallback()");
}
}
model->exitFunctionCallbacks.push_back(func_callback);
}
void ModelDescription::addExitConditionCallback(HostFunctionConditionCallback *func_callback) {
if (!model->exitConditionCallbacks.insert(func_callback).second) {
if (std::find(model->exitConditionCallbacks.begin(), model->exitConditionCallbacks.end(), func_callback) != model->exitConditionCallbacks.end()) {
THROW exception::InvalidHostFunc("Attempted to add same exit condition callback twice,"
"in ModelDescription::addExitConditionCallback()");
}
}
model->exitConditionCallbacks.push_back(func_callback);
}
#endif

Expand Down
12 changes: 8 additions & 4 deletions src/flamegpu/model/ModelDescription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,29 +136,33 @@ LayerDescription& ModelDescription::Layer(const std::string &name) {
}

void ModelDescription::addInitFunction(FLAMEGPU_INIT_FUNCTION_POINTER func_p) {
if (!model->initFunctions.insert(func_p).second) {
if (std::find(model->initFunctions.begin(), model->initFunctions.end(), func_p) != model->initFunctions.end()) {
THROW exception::InvalidHostFunc("Attempted to add same init function twice,"
"in ModelDescription::addInitFunction()");
}
model->initFunctions.push_back(func_p);
}
void ModelDescription::addStepFunction(FLAMEGPU_STEP_FUNCTION_POINTER func_p) {
if (!model->stepFunctions.insert(func_p).second) {
if (std::find(model->stepFunctions.begin(), model->stepFunctions.end(), func_p) != model->stepFunctions.end()) {
THROW exception::InvalidHostFunc("Attempted to add same step function twice,"
"in ModelDescription::addStepFunction()");
}
model->stepFunctions.push_back(func_p);
}
void ModelDescription::addExitFunction(FLAMEGPU_EXIT_FUNCTION_POINTER func_p) {
if (!model->exitFunctions.insert(func_p).second) {
if (std::find(model->exitFunctions.begin(), model->exitFunctions.end(), func_p) != model->exitFunctions.end()) {
THROW exception::InvalidHostFunc("Attempted to add same exit function twice,"
"in ModelDescription::addExitFunction()");
}
model->exitFunctions.push_back(func_p);
}

void ModelDescription::addExitCondition(FLAMEGPU_EXIT_CONDITION_POINTER func_p) {
if (!model->exitConditions.insert(func_p).second) {
if (std::find(model->exitConditions.begin(), model->exitConditions.end(), func_p) != model->exitConditions.end()) {
THROW exception::InvalidHostFunc("Attempted to add same exit condition twice,"
"in ModelDescription::addExitCondition()");
}
model->exitConditions.push_back(func_p);
}

void ModelDescription::generateLayers() {
Expand Down
32 changes: 24 additions & 8 deletions tests/test_cases/sim/test_host_functions.cu
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,12 @@ TEST_F(HostFunctionTest, InitFuncMultiple) {
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), Init), function_order.end());
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), Init2), function_order.end());
ms->run(1);
EXPECT_NE(std::find(function_order.begin(), function_order.end(), Init), function_order.end());
EXPECT_NE(std::find(function_order.begin(), function_order.end(), Init2), function_order.end());
auto it_1 = std::find(function_order.begin(), function_order.end(), Init);
auto it_2 = std::find(function_order.begin(), function_order.end(), Init2);
EXPECT_NE(it_1, function_order.end());
EXPECT_NE(it_2, function_order.end());
// Check that the exeuction order is correct. 2 should be after the previously added fn.
EXPECT_LT(it_1, it_2);
}
TEST_F(HostFunctionTest, HostLayerFuncMultiple) {
EXPECT_THROW(ms->hostfn_layer.addHostFunction(host_function2), exception::InvalidLayerMember);
Expand All @@ -163,24 +167,36 @@ TEST_F(HostFunctionTest, StepFuncMultiple) {
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), Step), function_order.end());
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), Step2), function_order.end());
ms->run(1);
EXPECT_NE(std::find(function_order.begin(), function_order.end(), Step), function_order.end());
EXPECT_NE(std::find(function_order.begin(), function_order.end(), Step2), function_order.end());
auto it_1 = std::find(function_order.begin(), function_order.end(), Step);
auto it_2 = std::find(function_order.begin(), function_order.end(), Step2);
EXPECT_NE(it_1, function_order.end());
EXPECT_NE(it_2, function_order.end());
// Check that the exeuction order is correct. 2 should be after the previously added fn.
EXPECT_LT(it_1, it_2);
}
TEST_F(HostFunctionTest, ExitConditionMultiple) {
ms->model.addExitCondition(exit_condition2);
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), ExitCondition), function_order.end());
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), ExitCondition2), function_order.end());
ms->run(1);
EXPECT_NE(std::find(function_order.begin(), function_order.end(), ExitCondition), function_order.end());
EXPECT_NE(std::find(function_order.begin(), function_order.end(), ExitCondition2), function_order.end());
auto it_1 = std::find(function_order.begin(), function_order.end(), ExitCondition);
auto it_2 = std::find(function_order.begin(), function_order.end(), ExitCondition2);
EXPECT_NE(it_1, function_order.end());
EXPECT_NE(it_2, function_order.end());
// Check that the exeuction order is correct. 2 should be after the previously added fn.
EXPECT_LT(it_1, it_2);
}
TEST_F(HostFunctionTest, ExitFuncMultiple) {
ms->model.addExitFunction(exit_function2);
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), Exit), function_order.end());
EXPECT_EQ(std::find(function_order.begin(), function_order.end(), Exit2), function_order.end());
ms->run(1);
EXPECT_NE(std::find(function_order.begin(), function_order.end(), Exit), function_order.end());
EXPECT_NE(std::find(function_order.begin(), function_order.end(), Exit2), function_order.end());
auto it_1 = std::find(function_order.begin(), function_order.end(), Exit);
auto it_2 = std::find(function_order.begin(), function_order.end(), Exit2);
EXPECT_NE(it_1, function_order.end());
EXPECT_NE(it_2, function_order.end());
// Check that the exeuction order is correct. 2 should be after the previously added fn.
EXPECT_LT(it_1, it_2);
}

/**
Expand Down

0 comments on commit f419323

Please sign in to comment.