Skip to content
6 changes: 0 additions & 6 deletions Core/include/Acts/Utilities/Any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,6 @@ class AnyBase : public AnyBaseAll {
}
}

template <typename T>
static std::uint64_t typeHash() {
const static std::uint64_t value = detail::fnv1a_64(typeid(T).name());
return value;
}

struct Handler {
void (*destroy)(void* ptr) = nullptr;
void (*moveConstruct)(void* from, void* to) = nullptr;
Expand Down
14 changes: 12 additions & 2 deletions Core/include/Acts/Utilities/HashedString.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
#include <cstddef>
#include <cstdint>
#include <string_view>
#include <type_traits>
#include <utility>
#include <typeinfo>

namespace Acts {
/// @brief Type alias for hashed string representation
Expand Down Expand Up @@ -76,4 +75,15 @@ constexpr HashedString operator""_hash(char const* s, std::size_t count) {
}

} // namespace HashedStringLiteral

/// Hash for a type. Since it's not possible to hash a type at compile-time,
/// this function returns a runtime hash but caches it in a static variable.
/// @tparam T Type to hash
/// @return Hashed string representation
template <typename T>
std::uint64_t typeHash() {
const static std::uint64_t value = detail::fnv1a_64(typeid(T).name());
return value;
}

} // namespace Acts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#pragma once

#include "Acts/Utilities/HashedString.hpp"
#include "ActsExamples/Framework/AlgorithmContext.hpp"
#include "ActsExamples/Framework/SequenceElement.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"
Expand Down Expand Up @@ -51,6 +52,7 @@ class DataHandleBase {
const std::string& key() const { return m_key.value(); }

virtual const std::type_info& typeInfo() const = 0;
virtual std::uint64_t typeHash() const = 0;

bool isInitialized() const { return m_key.has_value(); }

Expand Down Expand Up @@ -88,6 +90,10 @@ class DataHandleBase {
return wb.pop<T>(m_key.value());
}

WhiteBoard::IHolder* getHolder(const WhiteBoard& wb) const {
return wb.getHolder(m_key.value());
}

SequenceElement* m_parent{nullptr};
std::string m_name;
std::optional<std::string> m_key{};
Expand Down Expand Up @@ -180,6 +186,7 @@ class WriteDataHandle final : public WriteDataHandleBase {
}

const std::type_info& typeInfo() const override { return typeid(T); };
std::uint64_t typeHash() const override { return Acts::typeHash<T>(); };
};

/// A read handle for accessing data from the WhiteBoard.
Expand Down Expand Up @@ -213,6 +220,7 @@ class ReadDataHandle final : public ReadDataHandleBase {
}

const std::type_info& typeInfo() const override { return typeid(T); };
std::uint64_t typeHash() const override { return Acts::typeHash<T>(); };
};

/// A consume handle for taking ownership of data from the WhiteBoard.
Expand Down Expand Up @@ -247,6 +255,7 @@ class ConsumeDataHandle final : public ConsumeDataHandleBase {
}

const std::type_info& typeInfo() const override { return typeid(T); };
std::uint64_t typeHash() const override { return Acts::typeHash<T>(); };
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "Acts/Utilities/Concepts.hpp"
#include "Acts/Utilities/HashedString.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <algorithm>
Expand Down Expand Up @@ -36,13 +37,17 @@ class WhiteBoard {
struct IHolder {
virtual ~IHolder() = default;
virtual const std::type_info& type() const = 0;
virtual const void* data() const = 0;
virtual std::uint64_t typeHash() const = 0;
};
template <Acts::Concepts::nothrow_move_constructible T>
struct HolderT : public IHolder {
T value;

explicit HolderT(T&& v) : value(std::move(v)) {}
const std::type_info& type() const override { return typeid(T); }
std::uint64_t typeHash() const override { return Acts::typeHash<T>(); }
const void* data() const override { return std::addressof(value); }
};

struct StringHash {
Expand Down Expand Up @@ -116,6 +121,8 @@ class WhiteBoard {
template <typename T>
HolderT<T>* getHolder(const std::string& name) const;

IHolder* getHolder(const std::string& name) const;

template <typename T>
T pop(const std::string& name);

Expand Down
8 changes: 4 additions & 4 deletions Examples/Framework/src/Framework/DataHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "ActsExamples/Framework/Sequencer.hpp"

#include <regex>
#include <typeindex>
#include <typeinfo>

#include <boost/algorithm/string.hpp>
#include <boost/core/demangle.hpp>
Expand Down Expand Up @@ -73,8 +75,7 @@ void DataHandleBase::maybeInitialize(std::optional<std::string_view> key) {
}

bool WriteDataHandleBase::isCompatible(const DataHandleBase& other) const {
return dynamic_cast<const ReadDataHandleBase*>(&other) != nullptr &&
typeInfo() == other.typeInfo();
return typeHash() == other.typeHash();
}

void WriteDataHandleBase::emulate(StateMapType& state,
Expand Down Expand Up @@ -114,8 +115,7 @@ void ReadDataHandleBase::initialize(std::string_view key) {
}

bool ReadDataHandleBase::isCompatible(const DataHandleBase& other) const {
return dynamic_cast<const WriteDataHandleBase*>(&other) != nullptr &&
typeInfo() == other.typeInfo();
return typeHash() == other.typeHash();
}

void ReadDataHandleBase::emulate(StateMapType& state,
Expand Down
8 changes: 8 additions & 0 deletions Examples/Framework/src/Framework/WhiteBoard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,12 @@ std::vector<std::string> WhiteBoard::getKeys() const {
return keys;
}

WhiteBoard::IHolder *WhiteBoard::getHolder(const std::string &name) const {
auto it = m_store.find(name);
if (it == m_store.end()) {
throw std::out_of_range("Object '" + name + "' does not exists");
}
return it->second.get();
}

} // namespace ActsExamples
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class CollectionBaseWriteHandle : public WriteDataHandleBase {
/// Get the type info for this handle
/// @return The type info for std::unique_ptr<podio::CollectionBase>
const std::type_info& typeInfo() const override;

std::uint64_t typeHash() const override;
};

} // namespace ActsExamples
4 changes: 4 additions & 0 deletions Examples/Io/Podio/src/CollectionBaseWriteHandle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ const std::type_info& CollectionBaseWriteHandle::typeInfo() const {
return typeid(std::unique_ptr<podio::CollectionBase>);
}

std::uint64_t CollectionBaseWriteHandle::typeHash() const {
return Acts::typeHash<std::unique_ptr<podio::CollectionBase>>();
}

} // namespace ActsExamples
86 changes: 85 additions & 1 deletion Python/Examples/src/Framework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "Acts/Utilities/Logger.hpp"
#include "ActsExamples/Framework/AlgorithmContext.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Framework/IAlgorithm.hpp"
#include "ActsExamples/Framework/IReader.hpp"
#include "ActsExamples/Framework/IWriter.hpp"
Expand All @@ -16,9 +17,12 @@
#include "ActsExamples/Framework/SequenceElement.hpp"
#include "ActsExamples/Framework/Sequencer.hpp"
#include "ActsExamples/Framework/WhiteBoard.hpp"
#include "ActsPython/Utilities/Helpers.hpp"
#include "ActsPython/Utilities/Macros.hpp"
#include "ActsPython/Utilities/WhiteBoardTypeRegistry.hpp"

#include <stdexcept>

#include <boost/core/demangle.hpp>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

Expand Down Expand Up @@ -82,11 +86,74 @@ class PyIAlgorithm : public IAlgorithm {
}
}

ProcessCode initialize() override {
py::gil_scoped_acquire acquire{};
PYBIND11_OVERRIDE(ProcessCode, IAlgorithm, initialize, );
}

ProcessCode finalize() override {
py::gil_scoped_acquire acquire{};
PYBIND11_OVERRIDE(ProcessCode, IAlgorithm, finalize, );
}

std::string_view typeName() const override { return "Algorithm"; }

const Acts::Logger& pyLogger() const { return logger(); }
};

class PyReadDataHandle : public ReadDataHandleBase {
public:
PyReadDataHandle(SequenceElement* parent, py::object pytype,
const std::string& name)
: ReadDataHandleBase(parent, name) {
m_entry = WhiteBoardRegistry::find(pytype);
if (m_entry == nullptr) {
throw py::type_error("Type '" +
pytype.attr("__qualname__").cast<std::string>() +
"' is not registered for WhiteBoard access");
}
if (m_entry->typeinfo == nullptr) {
throw py::type_error("Type '" +
pytype.attr("__qualname__").cast<std::string>() +
"' is not registered for WhiteBoard access");
}

m_pytype = std::move(pytype);
registerAsReadHandle();
}

const std::type_info& typeInfo() const override { return *m_entry->typeinfo; }

std::uint64_t typeHash() const override { return m_entry->typeHash; }

py::object call(const py::object& wbPy) const {
if (!isInitialized()) {
throw std::runtime_error("ReadDataHandle '" + name() +
"' not initialized");
}
const auto& wb = wbPy.cast<const ActsExamples::WhiteBoard&>();

if (!wb.exists(key())) {
throw py::key_error("Key '" + key() + "' does not exist");
}

const auto& holder = getHolder(wb);

if (m_entry->typeHash != holder->typeHash()) {
const auto& expected = boost::core::demangle(m_entry->typeinfo->name());
const auto& actual = boost::core::demangle(holder->type().name());
throw py::type_error("Type mismatch for key '" + key() + "'. Expected " +
expected + " but got " + actual);
}

return m_entry->fn(holder->data(), wbPy);
}

private:
py::object m_pytype;
const WhiteBoardRegistry::RegistryEntry* m_entry{nullptr};
};

void trigger_divbyzero() {
volatile float j = 0.0;
volatile float r = 123 / j; // MARK: divbyzero
Expand Down Expand Up @@ -132,6 +199,23 @@ void addFramework(py::module& mex) {
.def("exists", &WhiteBoard::exists)
.def_property_readonly("keys", &WhiteBoard::getKeys);

py::class_<PyReadDataHandle>(mex, "ReadDataHandle")
.def(py::init([](const py::object& parent_py, py::object pytype,
const std::string& name) {
auto* parent = parent_py.cast<SequenceElement*>();
return std::make_unique<PyReadDataHandle>(parent,
std::move(pytype), name);
}),
py::arg("parent"), py::arg("type"), py::arg("name"),
py::keep_alive<1, 2>())
.def(
"initialize",
[](PyReadDataHandle& self, std::string_view key) {
self.initialize(key);
},
py::arg("key"))
.def("__call__", &PyReadDataHandle::call, py::arg("whiteboard"));

py::class_<AlgorithmContext>(mex, "AlgorithmContext")
.def(py::init<std::size_t, std::size_t, WhiteBoard&, std::size_t>(),
"alg"_a, "event"_a, "store"_a, "thread"_a)
Expand Down
11 changes: 10 additions & 1 deletion Python/Examples/src/Generators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "ActsExamples/Utilities/ParametricParticleGenerator.hpp"
#include "ActsExamples/Utilities/VertexGenerators.hpp"
#include "ActsPython/Utilities/Macros.hpp"
#include "ActsPython/Utilities/WhiteBoardTypeRegistry.hpp"

#include <cstddef>
#include <memory>
Expand Down Expand Up @@ -136,7 +137,15 @@ void addGenerators(py::module& mex) {
.def_readwrite("fixed", &FixedPrimaryVertexPositionGenerator::fixed);

py::class_<SimParticle>(mex, "SimParticle");
py::class_<SimParticleContainer>(mex, "SimParticleContainer");
auto simParticleContainer =
py::class_<SimParticleContainer>(mex, "SimParticleContainer")
.def("__len__",
[](const SimParticleContainer& self) { return self.size(); })
.def("__iter__", [](const SimParticleContainer& self) {
return py::make_iterator(self.begin(), self.end());
});

WhiteBoardRegistry::registerClass(simParticleContainer);

{
using Config = ParametricParticleGenerator::Config;
Expand Down
Loading
Loading