-
Notifications
You must be signed in to change notification settings - Fork 248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core] Remove push_back from ModelPart #12903
Open
sunethwarna
wants to merge
34
commits into
master
Choose a base branch
from
pvs/remove_push_back/core/model_part
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,089
−454
Open
Changes from 29 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
dd02fc8
add additional insert and typecheck to PVS
sunethwarna 2bf1e96
remove push_backs from ModelPart
sunethwarna 2c5d23f
include reduction_utils
sunethwarna d5521ba
minor
sunethwarna 2f72e0c
func name change
sunethwarna 1e98ea3
fix embedded_skin_utility for Id Change
sunethwarna 9c05b31
allow insertion from const vectors
sunethwarna abbce15
allow insertion from parent entity ranges
sunethwarna 71ae35f
fix for iterator invalidation
sunethwarna 6d34602
add comments
sunethwarna f1c4a6f
minor signature modification
sunethwarna 35c1874
fix assign_ms_const_to_neigh_utils
sunethwarna 13e87e7
fix error msg tests
sunethwarna a50fd2b
fix hdf5
sunethwarna 8a42759
generalize addition from ids
sunethwarna 93293e0
simplify
sunethwarna 6adabf4
fix ranged id addition
sunethwarna 9082f96
Merge remote-tracking branch 'origin/master' into pvs/remove_push_bac…
sunethwarna d7d4734
fix parmmg
sunethwarna d718a9a
add benchmarks for modelpart
sunethwarna 4430f5e
minor for comparison
sunethwarna d7e05de
add type_traits
sunethwarna fedc6b3
allow rvalue containers in pvs insert
sunethwarna d642295
allow rvalue containers in model part
sunethwarna ee29e90
tests for rvalue containers in PVS
sunethwarna 71e3074
more performance improvements
sunethwarna 1024156
fix tests
sunethwarna a9e8219
minor
sunethwarna abfdcab
bug fix
sunethwarna a00437f
fix sub range addition
sunethwarna 36fd864
add a test to subrange addition
sunethwarna 88a5f51
fix test
sunethwarna 22ff3e1
expose shrink_to_fit
sunethwarna 99aca1d
change test
sunethwarna File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,7 +36,10 @@ void PointsData::CreateNodes(NodesContainerType& rNodes) | |
const array_1d<double, 3>& r_coord = mCoords[i]; | ||
NodeType::Pointer p_node = Kratos::make_intrusive<NodeType>( | ||
mIds[i], r_coord[0], r_coord[1], r_coord[2]); | ||
rNodes.push_back(p_node); | ||
// here we can safely use the insert with the rNodes.end() as the hint | ||
// because, when reading, we can assume that it was written in the | ||
// sorted order within HDF5. | ||
rNodes.insert(rNodes.end(), p_node); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as before |
||
} | ||
KRATOS_CATCH(""); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
// | / | | ||
// ' / __| _` | __| _ \ __| | ||
// . \ | ( | | ( |\__ ` | ||
// _|\_\_| \__,_|\__|\___/ ____/ | ||
// Multi-Physics | ||
// | ||
// License: BSD License | ||
// Kratos default license: kratos/license.txt | ||
// | ||
// Main authors: Suneth Warnakulasuriya | ||
// | ||
|
||
// System includes | ||
#include <vector> | ||
|
||
// External includes | ||
#include <benchmark/benchmark.h> | ||
|
||
// Project includes | ||
#include "containers/model.h" | ||
#include "containers/pointer_vector_set.h" | ||
#include "includes/indexed_object.h" | ||
#include "includes/key_hash.h" | ||
#include "includes/model_part.h" | ||
#include "includes/smart_pointers.h" | ||
#include "utilities/assign_unique_model_part_collection_tag_utility.h" | ||
|
||
namespace Kratos { | ||
|
||
static void BM_ModelPartCreateNewNode(benchmark::State& state) { | ||
for (auto _ : state) { | ||
const IndexType input_size = state.range(0); | ||
|
||
state.PauseTiming(); | ||
|
||
auto model = Model(); | ||
auto& r_model_part = model.CreateModelPart("test"); | ||
|
||
state.ResumeTiming(); | ||
|
||
for (IndexType i = 0; i < input_size; ++i) { | ||
r_model_part.CreateNewNode(i + 1, 0.0, 0.0, 0.0); | ||
} | ||
} | ||
} | ||
|
||
|
||
static void BM_ModelPartAddNodesToRootFromRange1(benchmark::State& state) { | ||
for (auto _ : state) { | ||
const IndexType input_size = state.range(0); | ||
const bool fill_existing = state.range(1) == 1; | ||
|
||
state.PauseTiming(); | ||
|
||
auto model = Model(); | ||
auto& r_model_part = model.CreateModelPart("test"); | ||
|
||
std::vector<ModelPart::NodeType::Pointer> nodes_to_be_added, existing_nodes; | ||
if (!fill_existing) { | ||
nodes_to_be_added.reserve(input_size); | ||
} else { | ||
nodes_to_be_added.reserve(input_size / 2 + 1); | ||
existing_nodes.reserve(input_size / 2 + 1); | ||
} | ||
|
||
// doing it in reverse to make sure a proper sort is done always | ||
for (IndexType i = input_size; i > 0; --i) { | ||
auto p_node = Kratos::make_intrusive<NodeType>(i, 0.0, 0.0, 0.0); | ||
if (!fill_existing || i % 2 == 0) { | ||
nodes_to_be_added.push_back(p_node); | ||
} else { | ||
existing_nodes.push_back(p_node); | ||
} | ||
} | ||
r_model_part.AddNodes(existing_nodes.begin(), existing_nodes.end()); | ||
state.ResumeTiming(); | ||
|
||
// benchmarking to add nodes for already existing model part with nodes | ||
r_model_part.AddNodes(nodes_to_be_added.begin(), nodes_to_be_added.end()); | ||
} | ||
} | ||
|
||
static void BM_ModelPartAddNodesToRootFromRange2(benchmark::State& state) { | ||
for (auto _ : state) { | ||
const IndexType input_size = state.range(0); | ||
const bool fill_existing = state.range(1) == 1; | ||
|
||
state.PauseTiming(); | ||
|
||
auto model = Model(); | ||
auto& r_model_part = model.CreateModelPart("test"); | ||
|
||
PointerVectorSet<ModelPart::NodeType, IndexedObject> nodes_to_be_added, existing_nodes; | ||
if (!fill_existing) { | ||
nodes_to_be_added.reserve(input_size); | ||
} else { | ||
nodes_to_be_added.reserve(input_size / 2 + 1); | ||
existing_nodes.reserve(input_size / 2 + 1); | ||
} | ||
|
||
// doing it in reverse to make sure a proper sort is done always | ||
for (IndexType i = 0; i < input_size; ++i) { | ||
auto p_node = Kratos::make_intrusive<NodeType>(i + 1, 0.0, 0.0, 0.0); | ||
if (!fill_existing || i % 2 == 0) { | ||
nodes_to_be_added.insert(nodes_to_be_added.end(), p_node); | ||
} else { | ||
existing_nodes.insert(existing_nodes.end(), p_node); | ||
} | ||
} | ||
r_model_part.AddNodes(existing_nodes.begin(), existing_nodes.end()); | ||
state.ResumeTiming(); | ||
|
||
// benchmarking to add nodes for already existing model part with nodes | ||
r_model_part.AddNodes(nodes_to_be_added.begin(), nodes_to_be_added.end()); | ||
} | ||
} | ||
|
||
static void BM_ModelPartAddNodesToSubSubFromRange1(benchmark::State& state) { | ||
for (auto _ : state) { | ||
const IndexType input_size = state.range(0); | ||
const bool fill_existing = state.range(1) == 1; | ||
|
||
state.PauseTiming(); | ||
|
||
auto model = Model(); | ||
auto& r_sub_sub_model_part = model.CreateModelPart("test").CreateSubModelPart("sub_test").CreateSubModelPart("sub_sub_test"); | ||
|
||
std::vector<ModelPart::NodeType::Pointer> nodes_to_be_added, existing_nodes; | ||
if (!fill_existing) { | ||
nodes_to_be_added.reserve(input_size); | ||
} else { | ||
nodes_to_be_added.reserve(input_size / 2 + 1); | ||
existing_nodes.reserve(input_size / 2 + 1); | ||
} | ||
|
||
// doing it in reverse to make sure a proper sort is done always | ||
for (IndexType i = 0; i < input_size; ++i) { | ||
auto p_node = Kratos::make_intrusive<NodeType>(i + 1, 0.0, 0.0, 0.0); | ||
if (!fill_existing || i % 2 == 0) { | ||
nodes_to_be_added.insert(nodes_to_be_added.end(), p_node); | ||
} else { | ||
existing_nodes.insert(existing_nodes.end(), p_node); | ||
} | ||
} | ||
r_sub_sub_model_part.AddNodes(existing_nodes.begin(), existing_nodes.end()); | ||
state.ResumeTiming(); | ||
|
||
r_sub_sub_model_part.AddNodes(nodes_to_be_added.begin(), nodes_to_be_added.end()); | ||
} | ||
} | ||
|
||
static void BM_ModelPartAddNodesToSubSubFromRange2(benchmark::State& state) { | ||
for (auto _ : state) { | ||
const IndexType input_size = state.range(0); | ||
const bool fill_existing = state.range(1) == 1; | ||
|
||
state.PauseTiming(); | ||
|
||
auto model = Model(); | ||
auto& r_sub_sub_model_part = model.CreateModelPart("test").CreateSubModelPart("sub_test").CreateSubModelPart("sub_sub_test"); | ||
|
||
std::vector<ModelPart::NodeType::Pointer> nodes_to_be_added, existing_nodes; | ||
if (!fill_existing) { | ||
nodes_to_be_added.reserve(input_size); | ||
} else { | ||
nodes_to_be_added.reserve(input_size / 2 + 1); | ||
existing_nodes.reserve(input_size / 2 + 1); | ||
} | ||
|
||
// doing it in reverse to make sure a proper sort is done always | ||
for (IndexType i = 0; i < input_size; ++i) { | ||
auto p_node = Kratos::make_intrusive<NodeType>(i + 1, 0.0, 0.0, 0.0); | ||
if (!fill_existing || i % 2 == 0) { | ||
nodes_to_be_added.insert(nodes_to_be_added.end(), p_node); | ||
} else { | ||
existing_nodes.insert(existing_nodes.end(), p_node); | ||
} | ||
} | ||
r_sub_sub_model_part.GetRootModelPart().AddNodes(nodes_to_be_added.begin(), nodes_to_be_added.end()); | ||
r_sub_sub_model_part.GetRootModelPart().AddNodes(existing_nodes.begin(), existing_nodes.end()); | ||
state.ResumeTiming(); | ||
|
||
r_sub_sub_model_part.AddNodes(nodes_to_be_added.begin(), nodes_to_be_added.end()); | ||
} | ||
} | ||
|
||
static void BM_ModelPartAddNodesToSubSubFromRange3(benchmark::State& state) { | ||
for (auto _ : state) { | ||
const IndexType input_size = state.range(0); | ||
const bool fill_existing = state.range(1) == 1; | ||
|
||
state.PauseTiming(); | ||
|
||
auto model = Model(); | ||
auto& r_sub_sub_model_part = model.CreateModelPart("test").CreateSubModelPart("sub_test").CreateSubModelPart("sub_sub_test"); | ||
|
||
std::vector<ModelPart::NodeType::Pointer> nodes_to_be_added, existing_nodes; | ||
if (!fill_existing) { | ||
nodes_to_be_added.reserve(input_size); | ||
} else { | ||
nodes_to_be_added.reserve(input_size / 2 + 1); | ||
existing_nodes.reserve(input_size / 2 + 1); | ||
} | ||
|
||
// doing it in reverse to make sure a proper sort is done always | ||
for (IndexType i = 0; i < input_size; ++i) { | ||
auto p_node = Kratos::make_intrusive<NodeType>(i + 1, 0.0, 0.0, 0.0); | ||
if (!fill_existing || i % 2 == 0) { | ||
nodes_to_be_added.insert(nodes_to_be_added.end(), p_node); | ||
} else { | ||
existing_nodes.insert(existing_nodes.end(), p_node); | ||
} | ||
} | ||
r_sub_sub_model_part.GetRootModelPart().AddNodes(nodes_to_be_added.begin(), nodes_to_be_added.end()); | ||
r_sub_sub_model_part.GetRootModelPart().AddNodes(existing_nodes.begin(), existing_nodes.end()); | ||
state.ResumeTiming(); | ||
|
||
r_sub_sub_model_part.AddNodes(r_sub_sub_model_part.GetRootModelPart().NodesBegin(), r_sub_sub_model_part.GetRootModelPart().NodesEnd()); | ||
} | ||
} | ||
|
||
static void BM_ModelPartAddNodesToSubSubFromId1(benchmark::State& state) { | ||
for (auto _ : state) { | ||
const IndexType input_size = state.range(0); | ||
const bool fill_existing = state.range(1) == 1; | ||
|
||
state.PauseTiming(); | ||
|
||
auto model = Model(); | ||
auto& r_root_model_part = model.CreateModelPart("test"); | ||
auto& r_sub_sub_model_part = r_root_model_part.CreateSubModelPart("sub_test").CreateSubModelPart("sub_sub_test"); | ||
|
||
PointerVectorSet<ModelPart::NodeType, IndexedObject> nodes; | ||
std::vector<IndexType> node_ids_to_add, existing_node_ids; | ||
if (!fill_existing) { | ||
node_ids_to_add.reserve(input_size); | ||
} else { | ||
node_ids_to_add.reserve(input_size / 2 + 1); | ||
existing_node_ids.reserve(input_size / 2 + 1); | ||
} | ||
|
||
for (IndexType i = 0; i < input_size; ++i) { | ||
nodes.insert(nodes.end(), Kratos::make_intrusive<NodeType>(i + 1, 0.0, 0.0, 0.0)); | ||
RiccardoRossi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
// doing it in reverse to make sure a proper sort is done always | ||
for (IndexType i = input_size; i > 0; --i) { | ||
if (!fill_existing || i % 2 == 0) { | ||
node_ids_to_add.push_back(i); | ||
} else { | ||
existing_node_ids.push_back(i); | ||
} | ||
} | ||
r_root_model_part.AddNodes(nodes.begin(), nodes.end()); | ||
r_sub_sub_model_part.AddNodes(existing_node_ids); | ||
state.ResumeTiming(); | ||
|
||
r_sub_sub_model_part.AddNodes(node_ids_to_add); | ||
} | ||
} | ||
|
||
|
||
// Register the function as a benchmark | ||
BENCHMARK(BM_ModelPartCreateNewNode) -> RangeMultiplier(10) -> Range(1e2, 1e+6); | ||
BENCHMARK(BM_ModelPartAddNodesToRootFromRange1) -> ArgsProduct({{100, 1000, 10000, 100000, 1000000}, {0, 1}}); | ||
BENCHMARK(BM_ModelPartAddNodesToRootFromRange2) -> ArgsProduct({{100, 1000, 10000, 100000, 1000000}, {0, 1}}); | ||
BENCHMARK(BM_ModelPartAddNodesToSubSubFromRange1) -> ArgsProduct({{100, 1000, 10000, 100000, 1000000}, {0, 1}}); | ||
BENCHMARK(BM_ModelPartAddNodesToSubSubFromRange2) -> ArgsProduct({{100, 1000, 10000, 100000, 1000000}, {0, 1}}); | ||
BENCHMARK(BM_ModelPartAddNodesToSubSubFromRange3) -> ArgsProduct({{100, 1000, 10000, 100000, 1000000}, {0, 1}}); | ||
BENCHMARK(BM_ModelPartAddNodesToSubSubFromId1) -> ArgsProduct({{100, 1000, 10000, 100000, 1000000}, {0, 1}}); | ||
|
||
} // namespace Kratos | ||
|
||
BENCHMARK_MAIN(); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not efficient as you may be creating it out of order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It cannot be out of order, because we assume HDF5 files are written by the
HDF5Application
, hence when we write, we always write in the sorted order.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then i do not understand the role of mIds ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait, mIds is ordered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i'll accept the comment, but ... what if somone writes the hdf5 "by hand"? in that case it will be enormously expensive, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it will be expensive, but on the other hand, do we expect them to create HDF5 files by their own?, it needs to have a special structure. It it not impossible, but tedious.
If they are creating, then they can create them in sorted manner as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tend to lean with @sunethwarna point of view here. We just assume that id's are ordered here, or at least provide a mechanism to sort them before reaching this points. Not only the code is easier to read and do not need sorts in between, when we move to C++20 we can replace this with something like:
Which ensures that the view is inserted directly into
rElements
and remove the need for a temporal container with random access or the need to insert 1 by 1, which means that will be faster.