Files
TheRock/rocm-libraries/shared/rocroller/lib/include/rocRoller/Utilities/Component_Impl.hpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

250 lines
8.0 KiB
C++

// Copyright Advanced Micro Devices, Inc., or its affiliates.
// SPDX-License-Identifier: MIT
#pragma once
#include <rocRoller/Assemblers/Assembler.hpp>
#include <rocRoller/Utilities/Component.hpp>
#include <rocRoller/Utilities/Logging.hpp>
#include <rocRoller/Utilities/Utils.hpp>
#include <stdexcept>
namespace rocRoller
{
namespace Component
{
template <ComponentBase Base>
requires(!CSingleUse<Base>) std::shared_ptr<Base> Get(typename Base::Argument const& arg)
{
using Factory = ComponentFactory<Base>;
auto& factory = Factory::Instance();
return factory.get(arg);
}
template <ComponentBase Base>
requires(!CSingleUse<Base>) std::shared_ptr<Base> Get(typename Base::Argument&& arg)
{
using Factory = ComponentFactory<Base>;
auto const& factory = Factory::Instance();
return factory.get(arg);
}
// clang-format off
template <ComponentBase Base, typename Arg0, typename... Args>
requires(!CSingleUse<Base>
&& !std::same_as<typename Base::Argument, Arg0>
&& std::constructible_from<typename Base::Argument, Arg0, Args...>)
std::shared_ptr<Base> Get(Arg0 const& arg0, Args const&... args)
{
return Get<Base>(typename Base::Argument(arg0, args...));
}
// clang-format on
template <ComponentBase Base>
std::shared_ptr<Base> GetNew(typename Base::Argument const& arg)
{
using Factory = ComponentFactory<Base>;
auto& factory = Factory::Instance();
return factory.getNew(arg);
}
template <ComponentBase Base>
std::shared_ptr<Base> GetNew(typename Base::Argument&& arg)
{
using Factory = ComponentFactory<Base>;
auto& factory = Factory::Instance();
return factory.getNew(arg);
}
// clang-format off
template <ComponentBase Base, typename Arg0, typename... Args>
requires(!std::same_as<typename Base::Argument, Arg0>
&& std::constructible_from<typename Base::Argument, Arg0, Args...>)
std::shared_ptr<Base> GetNew(Arg0 const& arg0, Args const&... args)
{
return GetNew<Base>(typename Base::Argument(arg0, args...));
}
// clang-format on
template <Component Comp>
bool RegisterComponentImpl()
{
using Factory = ComponentFactory<typename Comp::Base>;
auto& factory = Factory::Instance();
return factory.template registerComponent<Comp>();
}
template <ComponentBase Base>
ComponentFactory<Base>::ComponentFactory()
{
ComponentFactory<Base>::registerImplementations();
}
template <ComponentBase Base>
ComponentFactory<Base>& ComponentFactory<Base>::Instance()
{
static ComponentFactory instance;
return instance;
}
template <ComponentBase Base>
template <typename T>
std::shared_ptr<Base> ComponentFactory<Base>::get(T&& arg) const
{
WriterLock lock{m_instanceCacheLock};
auto iter = m_instanceCache.find(arg);
if(iter != m_instanceCache.end())
{
return iter->second;
}
auto newInstance = getNew(arg);
m_instanceCache[std::forward<T>(arg)] = newInstance;
return newInstance;
}
template <ComponentBase Base>
template <typename T>
std::shared_ptr<Base> ComponentFactory<Base>::getNew(T&& arg) const
{
auto const& entry = getEntry(arg);
return entry.builder(std::forward<T>(arg));
}
template <ComponentBase Base>
template <typename T, bool Debug>
typename ComponentFactory<Base>::Entry const&
ComponentFactory<Base>::getEntry(T&& arg) const
{
WriterLock lock{m_entryCacheLock};
auto iter = m_entryCache.find(arg);
if(iter != m_entryCache.end())
{
return iter->second;
}
Entry const& e = findEntry<T, Debug>(arg);
return m_entryCache[std::forward<T>(arg)] = e;
}
template <ComponentBase Base>
template <typename T, bool Debug>
typename ComponentFactory<Base>::Entry const&
ComponentFactory<Base>::findEntry(T&& arg) const
{
ReaderLock lock{m_entriesLock};
auto foundIter = m_entries.end();
for(auto iter = m_entries.begin(); iter != m_entries.end(); iter++)
{
if(iter->matcher(std::forward<T>(arg)))
{
if(!Debug)
return *iter;
if(foundIter == m_entries.end())
{
foundIter = iter;
}
else
{
rocRoller::Log::warn("Multiple suitable components found for {}: {}, {}",
Base::Basename,
foundIter->name,
iter->name);
}
}
}
// TODO Investigate why cppcheck isn't ensuring that this macro
// is expanded correctly, requiring the derefInvalidIterator
// suppression.
AssertFatal(foundIter != m_entries.end(),
Base::Basename,
": No valid component found: ",
ShowValue(arg));
// cppcheck-suppress derefInvalidIterator
return *foundIter;
}
template <ComponentBase Base>
template <Component Comp>
bool ComponentFactory<Base>::registerComponent()
{
return registerComponent(Comp::Name, Comp::Match, Comp::Build);
}
template <ComponentBase Base>
bool ComponentFactory<Base>::registerComponent(std::string const& name,
Matcher<Base> matcher,
Builder<Base> builder)
{
if(name == "")
throw std::runtime_error(concatenate("Empty ", Base::Basename, " component name"));
auto sameName = [&name](auto const& entry) { return entry.name == name; };
WriterLock lock{m_entriesLock};
if(std::any_of(m_entries.begin(), m_entries.end(), sameName))
throw std::runtime_error(
concatenate("Duplicate ", Base::Basename, " component names: '", name, "'"));
RegisterBase(this);
m_entries.push_back({name, matcher, builder});
return true;
}
template <ComponentBase Base>
template <typename T>
void ComponentFactory<Base>::emptyCache(T&& arg)
{
{
WriterLock lock{m_entryCacheLock};
m_entryCache.erase(arg);
}
{
WriterLock lock{m_instanceCacheLock};
m_instanceCache.erase(arg);
}
}
template <ComponentBase Base>
void ComponentFactory<Base>::emptyCache()
{
{
WriterLock lock{m_entryCacheLock};
m_entryCache.clear();
}
{
WriterLock lock{m_instanceCacheLock};
m_instanceCache.clear();
}
}
inline void ComponentFactoryBase::ClearAllCaches()
{
for(auto ins : m_instances)
ins->emptyCache();
}
inline void ComponentFactoryBase::RegisterBase(ComponentFactoryBase* base)
{
m_instances.insert(base);
}
// std::unordered_set<ComponentFactoryBase *> ComponentFactoryBase::m_instances;
}
}