Skip to content
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

feat: parallel execution #124

Merged
merged 2 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions ecsact/entt/execution.hh
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ struct actions_map {
}

template<typename Action>
auto as_action_span() -> std::span<const Action*> {
auto as_action_span() const -> const std::span<const Action* const> {
ecsact_action_id action_id = Action::id;

if(!raw_value.contains(action_id)) {
Expand All @@ -78,8 +78,8 @@ struct actions_map {
auto& action_data_list = raw_value.at(action_id);
auto action_list_data_ptr = action_data_list.data();

return std::span<const Action*>{
reinterpret_cast<const Action**>(action_list_data_ptr),
return std::span<const Action* const>{
reinterpret_cast<const Action* const*>(action_list_data_ptr),
action_data_list.size(),
};
}
Expand All @@ -94,7 +94,8 @@ struct actions_map {
template<typename System>
auto execute_system( //
::entt::registry& registry,
ecsact_system_execution_context* parent
ecsact_system_execution_context* parent,
const ecsact::entt::actions_map& actions_map
) -> void {
static_assert(detail::unimplemented_by_codegen<System>, R"(
-----------------------------------------------------------------------------
Expand All @@ -114,8 +115,9 @@ auto execute_system( //
*/
template<typename Action>
auto execute_actions( //
::entt::registry& registry,
std::span<Action const*> action_range
::entt::registry& registry,
ecsact_system_execution_context* parent,
const ecsact::entt::actions_map& actions_map
) -> void {
static_assert(detail::unimplemented_by_codegen<Action>, R"(
-----------------------------------------------------------------------------
Expand All @@ -126,6 +128,12 @@ auto execute_actions( //
)");
}

using execute_fn_t = void (*)(
::entt::registry& registry,
ecsact_system_execution_context* parent,
const ecsact::entt::actions_map& actions_map
);

/**
* Allocates EnTT groups and storage if necessary for the system or action.
* NOTE: Template specializations are made available via the codegen plugin
Expand Down
9 changes: 9 additions & 0 deletions ecsact/entt/wrapper/core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,15 @@ inline auto prepare_component(ecsact_registry_id registry_id) -> void {
}
}

template<typename S>
inline auto prepare_system(ecsact_registry_id registry_id) -> void {
using namespace ecsact::entt::detail;
auto& reg = ecsact::entt::get_registry(registry_id);

reg.template storage<system_sorted<S>>();
reg.template storage<pending_lazy_execution<S>>();
}

template<typename C, typename V>
auto has_component_changed(entt::entity_id entity, V& view) -> bool {
using detail::exec_itr_beforechange_storage;
Expand Down
5 changes: 4 additions & 1 deletion rt_entt_codegen/core/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ cc_library(

# keep sorted
_CORE_CODEGEN_METHODS = {
"execute_systems": [],
"execute_systems": [
"//rt_entt_codegen/shared:parallel",
],
"create_registry": [],
"entity_matches": [
"//rt_entt_codegen/shared:sorting",
Expand All @@ -22,6 +24,7 @@ _CORE_CODEGEN_METHODS = {
"//rt_entt_codegen/shared:comps_with_caps",
"//rt_entt_codegen/shared:sorting",
"//rt_entt_codegen/shared:system_util",
"//rt_entt_codegen/shared:parallel",
"@entt//:entt",
"@ecsact_rt_entt//:lib",
],
Expand Down
5 changes: 5 additions & 0 deletions rt_entt_codegen/core/core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

namespace ecsact::rt_entt_codegen::core {

auto print_parallel_system_execute(
codegen_plugin_context& ctx,
const ecsact_entt_details& details
) -> void;

auto print_execute_systems( //
codegen_plugin_context& ctx,
const ecsact_entt_details& details
Expand Down
113 changes: 92 additions & 21 deletions rt_entt_codegen/core/execute_systems.cc
Original file line number Diff line number Diff line change
@@ -1,14 +1,44 @@
#include "core.hh"

#include "rt_entt_codegen/shared/parallel.hh"
#include "ecsact/lang-support/lang-cc.hh"
#include "rt_entt_codegen/shared/util.hh"
#include "ecsact/cpp_codegen_plugin_util.hh"

constexpr auto METHOD_BODY_TOP = R"(
auto& reg = ecsact::entt::get_registry(registry_id);
auto actions = ecsact::entt::actions_map{};
auto& registry = ecsact::entt::get_registry(registry_id);
auto actions_map = ecsact::entt::actions_map{};
)";

auto ecsact::rt_entt_codegen::core::print_parallel_system_execute(
codegen_plugin_context& ctx,
const ecsact_entt_details& details
) -> void {
using ecsact::cc_lang_support::cpp_identifier;
using ecsact::cpp_codegen_plugin_util::block;
using ecsact::rt_entt_codegen::util::method_printer;

ctx.write("template<std::size_t N>\n");
auto printer = //
method_printer{ctx, "execute_parallel_cluster"} //
.parameter("::entt::registry&", "registry")
.parameter("ecsact_system_execution_context*", "parent_context")
.parameter("std::array<exec_entry_t, N>", "system_arr")
.return_type("void");

block(
ctx,
"std::for_each(std::execution::par_unseq, system_arr.begin(), "
"system_arr.end(), [&registry](exec_entry_t pair)",
[&]() {
ctx.write("auto fn_ptr = pair.first;\n");
ctx.write("auto& actions_map = pair.second;\n");
ctx.write("fn_ptr(registry, nullptr, actions_map);");
}
);
ctx.write(");\n");
}

auto ecsact::rt_entt_codegen::core::print_execute_systems( //
codegen_plugin_context& ctx,
const ecsact_entt_details& details
Expand All @@ -33,7 +63,9 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
ctx.indentation += 1;
ctx.write("\n");

ctx.write("actions.collect(i, execution_count, execution_options_list);\n");
ctx.write( //
"actions_map.collect(i, execution_count, execution_options_list);\n"
);

block(ctx, "if(execution_options_list != nullptr)", [&] {
ctx.write(
Expand All @@ -45,26 +77,65 @@ auto ecsact::rt_entt_codegen::core::print_execute_systems( //
});
});

for(auto sys_like : details.top_execution_order) {
auto cpp_decl_name = cpp_identifier(ecsact::meta::decl_full_name(sys_like));
auto parallel_system_cluster =
ecsact::rt_entt_codegen::parallel::get_parallel_execution_cluster(
ctx,
details,
details.top_execution_order
);

if(details.is_action(sys_like)) {
ctx.write(
"ecsact::entt::execute_actions<",
cpp_decl_name,
">(reg, actions.as_action_span<",
cpp_decl_name,
">());\n"
);
} else if(details.is_system(sys_like)) {
ctx.write(
"ecsact::entt::execute_system<",
cpp_decl_name,
">(reg, nullptr);\n"
);
} else {
ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n");
for(const auto& systems_to_parallel : parallel_system_cluster) {
if(systems_to_parallel.size() == 1) {
auto sync_sys_id = systems_to_parallel[0];

auto sync_sys_name =
cpp_identifier(ecsact::meta::decl_full_name(sync_sys_id));

if(details.is_action(sync_sys_id)) {
ctx.write(std::format(
"ecsact::entt::execute_actions<{}>(registry, {}, "
"actions_map);\n",
sync_sys_name,
"nullptr"
));
}
if(details.is_system(sync_sys_id)) {
ctx.write(std::format(
"ecsact::entt::execute_system<{}>(registry, {}, "
"actions_map);\n",
sync_sys_name,
"nullptr"
));
}
continue;
}

ctx.write("execute_parallel_cluster(registry, nullptr, ");
ctx.write(std::format(
"std::array<exec_entry_t, {}> {{\n",
systems_to_parallel.size()
));
for(const auto system_like_id : systems_to_parallel) {
auto cpp_decl_name =
cpp_identifier(ecsact::meta::decl_full_name(system_like_id));

if(details.is_action(system_like_id)) {
ctx.write(
"\texec_entry_t{&ecsact::entt::execute_actions<",
cpp_decl_name,
">, actions_map},\n"
);
} else if(details.is_system(system_like_id)) {
ctx.write(
"\texec_entry_t{&ecsact::entt::execute_system<",
cpp_decl_name,
">, actions_map},\n"
);
} else {
ctx.write("// ??? unhandled ??? ", cpp_decl_name, "\n");
}
}
ctx.write("});\n");
}

ctx.write("\nupdate_all_beforechange_storage(registry_id);\n");
Expand Down
19 changes: 13 additions & 6 deletions rt_entt_codegen/core/init_registry_storage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,18 @@ auto ecsact::rt_entt_codegen::core::print_init_registry_storage(
for(auto comp_id : details.all_components) {
auto cpp_comp_name = cpp_identifier(decl_full_name(comp_id));

ctx.write(
"ecsact::entt::wrapper::core::prepare_component<",
cpp_comp_name,
">(registry_id)"
);
ctx.write(";\n");
ctx.write(std::format(
"ecsact::entt::wrapper::core::prepare_component<{}>(registry_id);\n",
cpp_comp_name
));
}

for(auto system_id : details.all_systems) {
auto cpp_sys_name = cpp_identifier(decl_full_name(system_id));

ctx.write(std::format(
"ecsact::entt::wrapper::core::prepare_system<{}>(registry_id);\n",
cpp_sys_name
));
}
}
Loading