Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b4970ff
[Patch] Move LayerLayout to new PatchDataLayout class
tdavidcl Jan 9, 2026
28dae97
[Patch] Move LayerLayout to new PatchDataLayout class
tdavidcl Jan 9, 2026
b6306de
authorship
tdavidcl Jan 9, 2026
4ec5272
address review
tdavidcl Jan 9, 2026
80d52df
noicer
tdavidcl Jan 10, 2026
98e3e7d
noicer
tdavidcl Jan 10, 2026
05532cc
it works
tdavidcl Jan 11, 2026
0254cc9
Merge branch 'main' into patch-2026-01-09-19-58
tdavidcl Jan 11, 2026
528b839
fix
tdavidcl Jan 11, 2026
830e4f1
Merge branch 'main' into patch-2026-01-09-19-58
tdavidcl Jan 11, 2026
077a6bd
Merge branch 'main' into patch-2026-01-09-19-58
tdavidcl Jan 27, 2026
1370bd5
Update src/shamrock/include/shamrock/patch/PatchDataLayout.hpp
tdavidcl Jan 27, 2026
61505cf
Merge branch 'main' into patch-2026-01-09-19-58
tdavidcl Jan 27, 2026
305114d
Update src/tests/shamrock/patch/PatchDataLayoutTests.cpp
tdavidcl Jan 27, 2026
cf7fc6b
Update src/shamrock/src/patch/PatchDataLayout.cpp
tdavidcl Jan 27, 2026
8bb890a
Merge branch 'main' into patch-2026-01-09-19-58
tdavidcl Jan 29, 2026
9f6b209
[gh-action] trigger CI with empty commit
github-actions[bot] Jan 29, 2026
b39e5f1
Merge branch 'main' into patch-2026-01-09-19-58
tdavidcl Feb 21, 2026
4ed61da
Merge branch 'main' into patch-2026-01-09-19-58
tdavidcl Feb 22, 2026
fdbd39c
bugfixed by using shamrock namespace
aserhani Feb 26, 2026
755eddc
got main layer ref
aserhani Feb 26, 2026
c0fb6bd
homogenized main layer index-label
aserhani Apr 20, 2026
d042116
Merge branch 'main_upstream' into FU1531
aserhani Apr 22, 2026
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
4 changes: 3 additions & 1 deletion src/shammodels/gsph/include/shammodels/gsph/Solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ namespace shammodels::gsph {
Config solver_config;
sph::SolverLog solve_logs;

inline void init_required_fields() { solver_config.set_layout(context.get_pdl_write()); }
inline void init_required_fields() {
solver_config.set_layout(context.get_pdl_write().get_layer_ref(0));
Comment thread
aserhani marked this conversation as resolved.
Outdated
}

// Serial patch tree control
void gen_serial_patch_tree();
Expand Down
4 changes: 3 additions & 1 deletion src/shammodels/ramses/include/shammodels/ramses/Solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ namespace shammodels::basegodunov {

SolverStorage<Tvec, TgridVec, u_morton> storage{};

inline void init_required_fields() { solver_config.set_layout(context.get_pdl_write()); }
inline void init_required_fields() {
solver_config.set_layout(context.get_pdl_write().get_layer_ref("main"));
}

Solver(ShamrockCtx &context) : context(context) {}

Expand Down
4 changes: 3 additions & 1 deletion src/shammodels/sph/include/shammodels/sph/Solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ namespace shammodels::sph {
Config solver_config;
SolverLog solve_logs;

inline void init_required_fields() { solver_config.set_layout(context.get_pdl_write()); }
inline void init_required_fields() {
solver_config.set_layout(context.get_pdl_write().get_layer_ref(0));
Comment thread
aserhani marked this conversation as resolved.
Outdated
}

// serial patch tree control
void gen_serial_patch_tree();
Expand Down
8 changes: 6 additions & 2 deletions src/shampylib/src/pyShamrockCtx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ Register_pymod(pyshamrockctxinit) {

py::dict dic_out;

using namespace shamrock;
if (ctx.pdl->get_layer_count() > 1) {
throw shambase::make_except_with_loc<std::runtime_error>(
"collect_data is not supported for multiple layers");
}

for (auto fname : ctx.pdl->get_field_names()) {
using namespace shamrock;
for (auto fname : ctx.pdl->get_layer_ref(0).get_field_names()) {
Comment thread
aserhani marked this conversation as resolved.
Outdated
append_to_map<f32>(fname, data, dic_out);
append_to_map<f32_2>(fname, data, dic_out);
append_to_map<f32_3>(fname, data, dic_out);
Expand Down
123 changes: 123 additions & 0 deletions src/shamrock/include/shamrock/patch/PatchDataLayout.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// -------------------------------------------------------//
//
// SHAMROCK code for hydrodynamics
// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
//
// -------------------------------------------------------//

#pragma once

/**
* @file PatchDataLayout.hpp
* @author Timothée David--Cléris (tim.shamrock@proton.me)
* @author Yona Lapeyre (yona.lapeyre@ens-lyon.fr)
* @brief
*/

#include "shambase/memory.hpp"
#include "shamrock/patch/PatchDataLayerLayout.hpp"
#include <initializer_list>
#include <memory>
#include <vector>

namespace shamrock::patch {

/**
* @brief PatchDataLayerLayout container class
* This class store the layout of the layers
*/
class PatchDataLayout {
public:
struct LayerEntry {
std::shared_ptr<shamrock::patch::PatchDataLayerLayout> layout;
std::string name;

inline friend bool operator==(const LayerEntry &lhs, const LayerEntry &rhs) {
return lhs.name == rhs.name
&& shambase::get_check_ref(lhs.layout)
== shambase::get_check_ref(rhs.layout);
}
};

std::vector<LayerEntry> layer_layouts;

PatchDataLayout() = default;

PatchDataLayout(const std::vector<std::string> &layer_names)
: layer_layouts{layer_names.size()} {
for (size_t i = 0; i < layer_layouts.size(); i++) {
layer_layouts[i].name = layer_names[i];
layer_layouts[i].layout = std::make_shared<PatchDataLayerLayout>();
}
}
Comment on lines +48 to +54

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This constructor can be implemented more idiomatically using modern C++ features like reserve and push_back with an initializer list. This avoids default-constructing LayerEntry objects and then re-assigning their members, which is slightly more efficient and readable.

        PatchDataLayout(const std::vector<std::string> &layer_names) {
            layer_layouts.reserve(layer_names.size());
            for (const auto &name : layer_names) {
                layer_layouts.push_back({std::make_shared<PatchDataLayerLayout>(), name});
            }
        }


PatchDataLayout(std::initializer_list<std::string> layer_names)
: PatchDataLayout(std::vector<std::string>(layer_names)) {}

size_t get_layer_count() const { return layer_layouts.size(); }

size_t get_layer_index(const std::string &name) const {
for (size_t i = 0; i < layer_layouts.size(); i++) {
if (layer_layouts[i].name == name) {
return i;
}
}
throw shambase::make_except_with_loc<std::invalid_argument>(
"the requested layer does not exists");
}
Comment on lines +61 to +69

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This loop can be replaced with std::find_if from the <algorithm> header for a more idiomatic C++ implementation. You will need to include <algorithm> and <iterator>.

        size_t get_layer_index(const std::string &name) const {
            auto it = std::find_if(layer_layouts.begin(), layer_layouts.end(),
                                   [&name](const LayerEntry &entry) {
                                       return entry.name == name;
                                   });

            if (it != layer_layouts.end()) {
                return std::distance(layer_layouts.begin(), it);
            }
            throw shambase::make_except_with_loc<std::invalid_argument>(
                "the requested layer does not exists");
        }


inline std::shared_ptr<PatchDataLayerLayout> &get_layer_ptr(size_t idx) {
return layer_layouts.at(idx).layout;
}

inline const std::shared_ptr<PatchDataLayerLayout> &get_layer_ptr(size_t idx) const {
return layer_layouts.at(idx).layout;
}

inline PatchDataLayerLayout &get_layer_ref(size_t idx) {
return shambase::get_check_ref(get_layer_ptr(idx));
}

inline std::shared_ptr<PatchDataLayerLayout> &get_layer_ptr(const std::string &name) {
return get_layer_ptr(get_layer_index(name));
}

inline const std::shared_ptr<PatchDataLayerLayout> &get_layer_ptr(
const std::string &name) const {
return get_layer_ptr(get_layer_index(name));
}

inline PatchDataLayerLayout &get_layer_ref(const std::string &name) {
return get_layer_ref(get_layer_index(name));
}

inline friend bool operator==(const PatchDataLayout &lhs, const PatchDataLayout &rhs) {
return lhs.layer_layouts == rhs.layer_layouts;
}
};

/**
* @brief Serialize a PatchDataLayout object to a JSON object
*
* This function takes a PatchDataLayout object and serializes it to a JSON object.
* It is used to convert the PatchDataLayout object to a JSON string.
*
* @param j The JSON object to serialize the PatchDataLayout object to
* @param p The PatchDataLayout object to serialize
*/
void to_json(nlohmann::json &j, const PatchDataLayout &p);

/**
* @brief Deserialize a PatchDataLayout object from a JSON object
*
* This function takes a JSON object and deserializes it to a PatchDataLayout object.
* It is used to convert a JSON string to a PatchDataLayout object.
*
* @param j The JSON object to deserialize the PatchDataLayout object from
* @param p The PatchDataLayout object to deserialize
*/
void from_json(const nlohmann::json &j, PatchDataLayout &p);

} // namespace shamrock::patch
26 changes: 22 additions & 4 deletions src/shamrock/include/shamrock/scheduler/PatchScheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "shambase/time.hpp"
#include "shamalgs/collective/distributedDataComm.hpp"
#include "shamrock/legacy/patch/utility/patch_field.hpp"
#include "shamrock/patch/PatchDataLayout.hpp"
#include "shamrock/solvergraph/NodeSetEdge.hpp"
#include "shamrock/solvergraph/PatchDataLayerRefs.hpp"
#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -64,7 +65,7 @@ class PatchScheduler {
using PatchTree = shamrock::scheduler::PatchTree;
using SchedulerPatchData = shamrock::scheduler::SchedulerPatchData;

std::shared_ptr<shamrock::patch::PatchDataLayerLayout> pdl_ptr;
std::shared_ptr<shamrock::patch::PatchDataLayout> pdl_ptr;

u64 crit_patch_split; ///< splitting limit (if load value > crit_patch_split => patch split)
u64 crit_patch_merge; ///< merging limit (if load value < crit_patch_merge => patch merge)
Expand All @@ -77,12 +78,29 @@ class PatchScheduler {
std::unordered_set<u64> owned_patch_id; ///< list of owned patch ids updated with
///< (owned_patch_id = patch_list.build_local())

inline shamrock::patch::PatchDataLayout &pdl() { return shambase::get_check_ref(pdl_ptr); }

inline std::shared_ptr<shamrock::patch::PatchDataLayout> get_layout_ptr() const {
return pdl_ptr;
}

/// Will be deprecated in favor of the new one with layout support
inline shamrock::patch::PatchDataLayerLayout &pdl_old() {
return shambase::get_check_ref(pdl_ptr);
auto &ref = pdl();
if (ref.get_layer_count() != 1) {
throw shambase::make_except_with_loc<std::invalid_argument>(
"pdl_old is not supported for multiple layers");
}
return ref.get_layer_ref(0);
}
Comment on lines 117 to 124

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To improve consistency with get_layout_ptr_old(), you can avoid calling pdl() here and instead directly get the reference from pdl_ptr. This makes both deprecated functions have a similar structure.

    inline shamrock::patch::PatchDataLayer &pdl_old() {
        auto &ref = shambase::get_check_ref(pdl_ptr);
        if (ref.get_layer_count() != 1) {
            throw shambase::make_except_with_loc<std::invalid_argument>(
                "pdl_old is not supported for multiple layers");
        }
        return ref.get_layer_ref(0);
    }


inline std::shared_ptr<shamrock::patch::PatchDataLayerLayout> get_layout_ptr_old() const {
return pdl_ptr;
auto &ref = shambase::get_check_ref(pdl_ptr);
if (ref.get_layer_count() != 1) {
throw shambase::make_except_with_loc<std::invalid_argument>(
"get_layout_ptr_old is not supported for multiple layers");
}
return ref.get_layer_ptr(0);
}

/**
Expand All @@ -98,7 +116,7 @@ class PatchScheduler {
void free_mpi_required_types();

PatchScheduler(
const std::shared_ptr<shamrock::patch::PatchDataLayerLayout> &pdl_ptr,
const std::shared_ptr<shamrock::patch::PatchDataLayout> &pdl_ptr,
u64 crit_split,
u64 crit_merge);

Expand Down
21 changes: 13 additions & 8 deletions src/shamrock/include/shamrock/scheduler/ShamrockCtx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ class ShamAPIException : public std::exception {

class ShamrockCtx {
public:
std::shared_ptr<shamrock::patch::PatchDataLayerLayout> pdl;
std::shared_ptr<shamrock::patch::PatchDataLayout> pdl;
std::unique_ptr<PatchScheduler> sched;

inline void pdata_layout_new() {
if (sched) {
throw ShamAPIException("cannot modify patch data layout while the scheduler is on");
}
pdl = std::make_shared<shamrock::patch::PatchDataLayerLayout>();
pdl = std::make_shared<shamrock::patch::PatchDataLayout>(std::vector<std::string>{"main"});
}

// inline void pdata_layout_do_double_prec_mode(){
Expand All @@ -65,7 +65,7 @@ class ShamrockCtx {
// pdl->xyz_mode = xyz32;
//}

inline shamrock::patch::PatchDataLayerLayout &get_pdl_write() {
inline shamrock::patch::PatchDataLayout &get_pdl_write() {
if (sched) {
throw ShamAPIException("cannot modify patch data layout while the scheduler is on");
}
Expand All @@ -77,21 +77,22 @@ class ShamrockCtx {
if (sched) {
throw ShamAPIException("cannot modify patch data layout while the scheduler is on");
}
pdl->add_field<T>(fname, nvar);
shambase::get_check_ref(pdl).get_layer_ref("main").add_field<T>(fname, nvar);
}

inline void pdata_layout_add_field_t(std::string fname, u32 nvar, std::string type) {
if (sched) {
throw ShamAPIException("cannot modify patch data layout while the scheduler is on");
}
pdl->add_field_t(fname, nvar, type);
shambase::get_check_ref(pdl).get_layer_ref("main").add_field_t(fname, nvar, type);
}
Comment on lines 83 to 88

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to pdata_layout_add_field, you can use get_pdl_write() here to simplify the code and avoid duplicating the check for sched.

    inline void pdata_layout_add_field_t(std::string fname, u32 nvar, std::string type) {
        get_pdl_write().get_layer_ref("main").add_field_t(fname, nvar, type);
    }


inline void pdata_layout_print() {
if (!pdl) {
throw ShamAPIException("patch data layout is not initialized");
}
std::cout << pdl->get_description_str() << std::endl;
std::cout << shambase::get_check_ref(pdl).get_layer_ref("main").get_description_str()
<< std::endl;
}
Comment on lines 90 to 96

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The if (!pdl) check is redundant because shambase::get_check_ref(pdl) will throw an exception if pdl is a null pointer. You can safely remove the if block.

    inline void pdata_layout_print() {
        std::cout << shambase::get_check_ref(pdl).get_layer_ref("main").get_description_str()
                  << std::endl;
    }


inline void dump_status() {
Expand Down Expand Up @@ -154,9 +155,13 @@ class ShamrockCtx {
throw ShamAPIException("scheduler is not initialized");
}

if (pdl->get_layer_count() > 1) {
throw ShamAPIException("set_coord_domain_bound is not supported for multiple layers");
}

auto [a, b] = box;

if (pdl->check_main_field_type<f32_3>()) {
if (pdl->get_layer_ref("main").check_main_field_type<f32_3>()) {
auto conv_vec = [](f64_3 v) -> f32_3 {
return {v.x(), v.y(), v.z()};
};
Expand All @@ -165,7 +170,7 @@ class ShamrockCtx {
f32_3 vec1 = conv_vec(b);

sched->set_coord_domain_bound<f32_3>(vec0, vec1);
} else if (pdl->check_main_field_type<f64_3>()) {
} else if (pdl->get_layer_ref("main").check_main_field_type<f64_3>()) {

sched->set_coord_domain_bound<f64_3>(a, b);
} else {
Expand Down
10 changes: 8 additions & 2 deletions src/shamrock/src/io/ShamrockDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ namespace shamrock {

StackEntry stack_loc{};

if (shambase::get_check_ref(ctx.pdl).get_layer_count() > 1) {
throw shambase::make_except_with_loc<std::runtime_error>(
"load_shamrock_dump is not supported for multiple layers");
}

u64 head_ptr = 0;
MPI_File mfile{};

Expand Down Expand Up @@ -190,7 +195,7 @@ namespace shamrock {
json jpdat_info = json::parse(patchdata_infos);

ctx.pdata_layout_new();
*ctx.pdl = jmeta_patch.at("patchdata_layout").get<patch::PatchDataLayerLayout>();
*ctx.pdl = jmeta_patch.at("patchdata_layout").get<patch::PatchDataLayout>();
ctx.init_sched(
jmeta_patch.at("crit_patch_split").get<u64>(),
jmeta_patch.at("crit_patch_merge").get<u64>());
Expand Down Expand Up @@ -246,7 +251,8 @@ namespace shamrock {
shamalgs::SerializeHelper ser(
shamsys::instance::get_compute_scheduler_ptr(), std::move(out));

patch::PatchDataLayer pdat = patch::PatchDataLayer::deserialize_buf(ser, ctx.pdl);
patch::PatchDataLayer pdat = patch::PatchDataLayer::deserialize_buf(
ser, shambase::get_check_ref(ctx.pdl).get_layer_ptr(0));
Comment thread
aserhani marked this conversation as resolved.
Outdated

sched.patch_data.owned_data.add_obj(pid, std::move(pdat));
}
Expand Down
Loading
Loading