.. _program_listing_file_SeQuant_domain_eval_cache_manager.cpp: Program Listing for File cache_manager.cpp ========================================== |exhale_lsh| :ref:`Return to documentation for file ` (``SeQuant/domain/eval/cache_manager.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // // Created by Bimal Gaudel on 9/26/23. // #include #include namespace sequant { CacheManager::entry::entry(size_t count) noexcept : max_life{count}, // life_c{count}, // data_p{nullptr} {} ERPtr CacheManager::entry::access() noexcept { if (!data_p) return nullptr; return decay() == 0 ? std::move(data_p) : data_p; } void CacheManager::entry::store(ERPtr data) noexcept { data_p = data; } void CacheManager::entry::reset() noexcept { life_c = max_life; data_p = nullptr; } [[nodiscard]] size_t CacheManager::entry::life_count() const noexcept { return life_c; } [[nodiscard]] size_t CacheManager::entry::max_life_count() const noexcept { return max_life; } [[nodiscard]] int CacheManager::entry::decay() noexcept { return life_c > 0 ? static_cast(--life_c) : 0; } ERPtr CacheManager::store(CacheManager::entry& entry, ERPtr data) noexcept { entry.store(data); return entry.access(); } void CacheManager::reset() noexcept { for (auto&& [k, v] : cache_map_) v.reset(); } ERPtr CacheManager::access(key_type key) noexcept { if (auto&& found = cache_map_.find(key); found != cache_map_.end()) return found->second.access(); return nullptr; } ERPtr CacheManager::store(key_type key, ERPtr data) noexcept { if (auto&& found = cache_map_.find(key); found != cache_map_.end()) return store(found->second, data); return data; } bool CacheManager::exists(key_type key) const noexcept { return cache_map_.find(key) != cache_map_.end(); } int CacheManager::life(key_type key) const noexcept { auto iter = cache_map_.find(key); auto end = cache_map_.end(); return iter == end ? -1 : static_cast(iter->second.life_count()); } int CacheManager::max_life(key_type key) const noexcept { auto iter = cache_map_.find(key); auto end = cache_map_.end(); return iter == end ? -1 : static_cast(iter->second.max_life_count()); } container::set CacheManager::keys() const noexcept { return ranges::views::keys(cache_map_) | ranges::to>; } CacheManager CacheManager::empty() noexcept { return CacheManager{{}}; } template >> void max_cache(NodeT const& node, // CacheManager& cm, // AsyCost& curr, // AsyCost& max) { auto const k = hash::value(*node); if (auto ptr = cm.access(k); ptr) { // std::cout << "[ACCESS][" << k << "]\n"; if (cm.life(k) == 0) { curr -= Memory{}(node); // std::cout << "[RELEASE][" << k << "]\n"; } return; } if (!node.leaf()) { max_cache(node.left(), cm, curr, max); max_cache(node.right(), cm, curr, max); if (cm.exists(k)) { curr += Memory{}(node); max = std::max(curr, max); // simulate cache store auto s = cm.store(k, eval_result>(0)); // std::cout << "[STORE][" << k << "]\n"; // std::cout << "[ACCESS][" << k << "]\n"; } } } AsyCost peak_cache(Sum const& expr) { auto const nodes = expr | ranges::views::transform(eval_node); auto cm = cache_manager(nodes); auto max = AsyCost::zero(); auto curr = AsyCost::zero(); for (auto const& n : nodes) max_cache(n, cm, curr, max); return max; } } // namespace sequant