#ifndef __SD_CORE_PE_CACHE_H__ #define __SD_CORE_PE_CACHE_H__ #include #include #include #include #include "core/tensor.hpp" #include "ggml.h" namespace sd { class PECacheKey { std::string name_; std::string fields_; public: explicit PECacheKey(std::string name) : name_(std::move(name)) {} const std::string& name() const { return name_; } template || std::is_enum_v, int> = 0> PECacheKey& add(T value) { if constexpr (std::is_floating_point_v) { const double field = static_cast(value); fields_.push_back('f'); fields_.append(reinterpret_cast(&field), sizeof(field)); } else { const uint64_t field = static_cast(value); fields_.push_back('i'); fields_.append(reinterpret_cast(&field), sizeof(field)); } return *this; } template PECacheKey& add(const std::vector& values) { fields_.push_back('v'); add(values.size()); for (const auto& value : values) { add(value); } return *this; } template PECacheKey& add(const std::set& values) { return add(std::vector(values.begin(), values.end())); } template PECacheKey& add(const Tensor& values) { add(values.shape()); for (int64_t i = 0; i < values.numel(); ++i) { add(values.data()[i]); } return *this; } PECacheKey& add_shape(const ggml_tensor* tensor); PECacheKey& add_shapes(const std::vector& tensors); bool operator==(const PECacheKey& other) const { return name_ == other.name_ && fields_ == other.fields_; } }; class PECache { struct Entry { PECacheKey key; Tensor value; }; std::map entries_; public: const Tensor& get_or_create(const PECacheKey& key, const std::function()>& build); }; } #endif // __SD_CORE_PE_CACHE_H__