Skip to content

feat: abort messages #979

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

Merged
merged 1 commit into from
Apr 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
8 changes: 7 additions & 1 deletion core/include/detray/navigation/direct_navigator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,18 @@ class direct_navigator {
}

DETRAY_HOST_DEVICE
inline auto abort() -> bool {
inline auto abort(const char * = nullptr) -> bool {
m_status = navigation::status::e_abort;
m_heartbeat = false;
return m_heartbeat;
}

template <typename debug_msg_generator_t>
DETRAY_HOST_DEVICE inline auto abort(const debug_msg_generator_t &)
-> bool {
return abort();
}

DETRAY_HOST_DEVICE
inline auto exit() -> bool {
m_status = navigation::status::e_on_target;
Expand Down
59 changes: 56 additions & 3 deletions core/include/detray/navigation/navigator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,15 +394,54 @@ class navigator {
/// Navigation state that cannot be recovered from. Leave the other
/// data for inspection.
///
/// @param custom_msg additional information on the reason for the error
///
/// @return navigation heartbeat (dead)
DETRAY_HOST_DEVICE
inline auto abort() -> bool {
inline auto abort(const char *custom_msg = "Navigator (unkown reason)")
-> bool {
m_status = navigation::status::e_abort;
m_heartbeat = false;
// Don't do anything if aborted
m_trust_level = navigation::trust_level::e_full;

/// Wrapper around the custom message that a print inspector can
/// understand
struct message_wrapper {
const char *const m_msg{nullptr};

DETRAY_HOST_DEVICE
constexpr const char *operator()() const { return m_msg; }
};

assert(custom_msg != nullptr);
run_inspector({}, point3_type{0.f, 0.f, 0.f},
vector3_type{0.f, 0.f, 0.f},
"Aborted: ", message_wrapper{custom_msg});

return m_heartbeat;
}

/// Navigation state that cannot be recovered from. Leave the other
/// data for inspection.
///
/// @param debug_msg_generator functor that returns additional
/// information on the reason for the error
///
/// @return navigation heartbeat (dead)
template <typename debug_msg_generator_t>
requires(!std::same_as<char *, debug_msg_generator_t>)
DETRAY_HOST_DEVICE
inline auto abort(const debug_msg_generator_t &debug_msg_generator)
-> bool {
m_status = navigation::status::e_abort;
m_heartbeat = false;
m_trust_level = navigation::trust_level::e_full;

run_inspector({}, point3_type{0.f, 0.f, 0.f},
vector3_type{0.f, 0.f, 0.f}, "Aborted: ");
vector3_type{0.f, 0.f, 0.f},
"Aborted: ", debug_msg_generator);

return m_heartbeat;
}

Expand Down Expand Up @@ -579,6 +618,20 @@ class navigator {
}
}

/// Call the navigation inspector
template <typename debug_msg_generator_t>
DETRAY_HOST_DEVICE inline void run_inspector(
[[maybe_unused]] const navigation::config &cfg,
[[maybe_unused]] const point3_type &track_pos,
[[maybe_unused]] const vector3_type &track_dir,
[[maybe_unused]] const char *message,
[[maybe_unused]] const debug_msg_generator_t &msg_gen) {
if constexpr (!std::is_same_v<inspector_t,
navigation::void_inspector>) {
m_inspector(*this, cfg, track_pos, track_dir, message, msg_gen);
}
}

/// Our cache of candidates (intersections with any kind of surface)
candidate_cache_t m_candidates;

Expand Down Expand Up @@ -788,7 +841,7 @@ class navigator {
// Unrecoverable
if (navigation.trust_level() != navigation::trust_level::e_full ||
navigation.is_exhausted()) {
navigation.abort();
navigation.abort("Navigator: No reachable surfaces");
}

return is_init;
Expand Down
9 changes: 6 additions & 3 deletions core/include/detray/propagator/actors/aborters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ struct pathlimit_aborter : actor {
// Check the path limit
if (step_limit <= 0.f) {
// Stop navigation
prop_state._heartbeat &= nav_state.abort();
prop_state._heartbeat &=
nav_state.abort("Aborter: Maximal path length reached");
}

// Don't go over the path limit in the next step
Expand Down Expand Up @@ -123,7 +124,8 @@ struct momentum_aborter : actor {

if (mag <= abrt_state.p_limit()) {
// Stop navigation
prop_state._heartbeat &= nav_state.abort();
prop_state._heartbeat &=
nav_state.abort("Aborter: Minimum momentum reached");
}
}
};
Expand Down Expand Up @@ -153,7 +155,8 @@ struct target_aborter : actor {
if (navigation.is_on_surface() &&
(navigation.barcode() == abrt_state._target_surface) &&
(stepping.path_length() > 0.f)) {
prop_state._heartbeat &= navigation.abort();
prop_state._heartbeat &=
navigation.abort("Aborter: Reached target surface");
}
}
};
Expand Down
66 changes: 48 additions & 18 deletions tests/include/detray/test/utils/inspectors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,32 +56,38 @@ struct aggregate_inspector {

/// Inspector interface
template <unsigned int current_id = 0, typename state_type,
concepts::point3D point3_t, concepts::vector3D vector3_t>
concepts::point3D point3_t, concepts::vector3D vector3_t,
typename... Args>
DETRAY_HOST_DEVICE auto operator()(state_type &state,
const navigation::config &cfg,
const point3_t &pos,
const vector3_t &dir,
const char *message) {
const char *message, Args &&... args) {
// Call inspector
std::get<current_id>(_inspectors)(state, cfg, pos, dir, message);
std::get<current_id>(_inspectors)(state, cfg, pos, dir, message,
std::forward<Args>(args)...);

// Next inspector
if constexpr (current_id <
std::tuple_size<inspector_tuple_t>::value - 1) {
return operator()<current_id + 1>(state, cfg, pos, dir, message);
return operator()<current_id + 1>(state, cfg, pos, dir, message,
std::forward<Args>(args)...);
}
}

/// Inspector interface
template <unsigned int current_id = 0, typename state_type>
DETRAY_HOST_DEVICE auto operator()(state_type &state, const char *message) {
template <unsigned int current_id = 0, typename state_type,
typename... Args>
DETRAY_HOST_DEVICE auto operator()(state_type &state, const char *message,
Args &&... args) {
// Call inspector
std::get<current_id>(_inspectors)(state, message);

// Next inspector
if constexpr (current_id <
std::tuple_size<inspector_tuple_t>::value - 1) {
return operator()<current_id + 1>(state, message);
return operator()<current_id + 1>(state, message,
std::forward<Args>(args)...);
}
}

Expand Down Expand Up @@ -191,12 +197,12 @@ struct object_tracer {

/// Inspector interface
template <typename state_type, concepts::point3D point3_t,
concepts::vector3D vector3_t>
concepts::vector3D vector3_t, typename... Args>
DETRAY_HOST_DEVICE auto operator()(const state_type &state,
const navigation::config &,
const point3_t &pos,
const vector3_t &dir,
const char * /*message*/) {
const char * /*message*/, Args &&...) {

// Record the candidate of an encountered object
if ((is_status(state.status(), navigation_status) || ...)) {
Expand Down Expand Up @@ -245,6 +251,8 @@ struct print_inspector {
using view_type = dvector_view<char>;
using const_view_type = dvector_view<const char>;

struct void_generator {};

/// Default constructor
print_inspector() = default;

Expand Down Expand Up @@ -272,17 +280,24 @@ struct print_inspector {
/// Move assignemten operator
print_inspector &operator=(print_inspector &&other) = default;

/// Gathers navigation information accross navigator update calls
std::stringstream debug_stream{};

/// Inspector interface. Gathers detailed information during navigation
template <typename state_type, concepts::point3D point3_t,
concepts::vector3D vector3_t>
concepts::vector3D vector3_t,
typename message_generator_t = void_generator>
auto operator()(const state_type &state, const navigation::config &cfg,
const point3_t &track_pos, const vector3_t &track_dir,
const char *message) {
const char *message,
const message_generator_t &msg_gen = {}) {
std::string msg(message);
debug_stream << msg << std::endl;
debug_stream << msg;
if constexpr (!std::same_as<message_generator_t, void_generator>) {
debug_stream << msg_gen();

if (state.status() == navigation::status::e_abort) {
fata_error_msg = msg_gen();
}
}
debug_stream << std::endl;
debug_stream << "----------------------------------------" << std::endl;

debug_stream << navigation::print_state(state);
Expand All @@ -293,10 +308,20 @@ struct print_inspector {
}

/// Inspector interface. Print basic state information
template <typename state_type>
auto operator()(const state_type &state, const char *message) {
template <typename state_type,
typename message_generator_t = void_generator>
auto operator()(const state_type &state, const char *message,
const message_generator_t &msg_gen = {}) {
std::string msg(message);
debug_stream << msg << std::endl;
debug_stream << msg;
if constexpr (!std::same_as<message_generator_t, void_generator>) {
debug_stream << msg_gen();

if (state.status() == navigation::status::e_abort) {
fata_error_msg = msg_gen();
}
}
debug_stream << std::endl;
debug_stream << "----------------------------------------" << std::endl;

debug_stream << navigation::print_state(state);
Expand All @@ -306,6 +331,11 @@ struct print_inspector {

/// @returns a string representation of the gathered information
std::string to_string() const { return debug_stream.str(); }

/// Gathers navigation information accross navigator update calls
std::stringstream debug_stream{};
/// Special message that is collected if the navigator hits a fatal error
std::string fata_error_msg{""};
};

} // namespace navigation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1074,10 +1074,10 @@ auto compare_to_navigation(

// Fatal propagation error: Data unreliable
if (!success) {
std::cout << "ERROR: Propagation failure" << std::endl;
std::cout << "ERROR: Propagation aborted! "
<< nav_printer.fata_error_msg << std::endl;

*debug_file << "ERROR: Propagation failure:\n"
<< "TEST TRACK " << i;
*debug_file << "ERROR: Propagation aborted:" << std::endl;

n_fatal_error++;
}
Expand Down
Loading