// Copyright Advanced Micro Devices, Inc., or its affiliates. // SPDX-License-Identifier: MIT #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace rocRoller { /** * @brief Base class for SettingsOption. * * Keeps track of its instances, so do not create temporaries. */ struct SettingsOptionBase { std::string name; std::string description; SettingsOptionBase(std::string name, std::string description); virtual std::string help() const; virtual std::optional getFromEnv() const = 0; virtual std::any getDefault() const = 0; virtual int getBitIndex() const = 0; /** * @brief Getter for instances. */ static std::vector const& instances(); private: inline static std::vector m_instances; }; /** * @brief Options are represented by the SettingsOption struct. * * @tparam T type of underlying option. */ template struct SettingsOption : public SettingsOptionBase { using Type = T; using DefaultValueType = typename std::conditional, T>::type; DefaultValueType defaultValue; int bit; SettingsOption(std::string name, std::string description, DefaultValueType defaultValue, int bit); std::string help() const override; std::optional getFromEnv() const override; std::any getDefault() const override; int getBitIndex() const override; T getTypeValue(std::string const&) const; T getValue() const; }; std::string toString(LogLevel level); std::ostream& operator<<(std::ostream&, LogLevel const&); /** * @brief Settings class is derived from lazy singleton class and handles options * that are defined through environment variables or developer defined options. * * Getting a value requires a call to get(SettingsOption opt). When get() is called, * we probe m_values which maps an option name to its corresponding value. If opt does * not exist in m_values then we assign the value based on the following precedence order: * 1. the corresponding env variable will be used. If no env variable is set then * 2. the default value is used if the value is not otherwise obtained. * * A call to set(SettingsOption opt) sets (or overwrites) the corresponding value in m_values. */ class Settings : public LazySingleton { public: using bitFieldType = std::bitset<32>; static inline const SettingsOption LogConsole{ "ROCROLLER_LOG_CONSOLE", "Log debug info to stdout/stderr", true, 0}; static inline const SettingsOption SaveAssembly{ "ROCROLLER_SAVE_ASSEMBLY", "Assembly code written to text file in the current working directory as it is " "generated", false, 1}; static inline const SettingsOption BreakOnThrow{ "ROCROLLER_BREAK_ON_THROW", "Cause exceptions thrown to cause a segfault", false, 2}; static inline const SettingsOption ROCMPath{ "ROCM_PATH", "Path where ROCM is installed", "/opt/rocm", -1}; static inline const SettingsOption ArchitectureFile{ "ROCROLLER_ARCHITECTURE_FILE", "GPU Architecture file", "", -1}; static inline const SettingsOption AssemblyFile{ "ROCROLLER_ASSEMBLY_FILE", "File name to write assembly", "", -1}; static inline const SettingsOption LogFile{ "ROCROLLER_LOG_FILE", "Log file name", "", -1}; static inline const SettingsOption Scheduler{ "ROCROLLER_SCHEDULER", "Scheduler used when scheduling independent instruction streams.", Scheduling::SchedulerProcedure::Priority, -1}; static inline const SettingsOption SchedulerCost{ "ROCROLLER_SCHEDULER_COST", "Default cost function for schedulers.", Scheduling::CostFunction::LinearWeighted, -1}; static inline const SettingsOption SchedulerWeights{ "ROCROLLER_SCHEDULER_WEIGHTS", "Scheduler Weight (YAML) File for LinearWeighted cost function.", "", -1}; static inline const SettingsOption LogLvl{ "ROCROLLER_LOG_LEVEL", "Log level", LogLevel::None, -1}; static inline const SettingsOption LogFileLvl{ "ROCROLLER_LOG_FILE_LEVEL", "Log level for output to the log file", LogLevel::None, -1}; static inline const SettingsOption LogConsoleLvl{ "ROCROLLER_LOG_CONSOLE_LEVEL", "Log level for output to the console", LogLevel::None, -1}; static inline const SettingsOption RandomSeed{"ROCROLLER_RANDOM_SEED", "Seed used with RandomGenerator class", std::numeric_limits::min(), -1}; static inline const SettingsOption KernelAnalysis{ "ROCROLLER_KERNEL_ANALYSIS", "Whether to track and report register liveness.", false, -1}; static inline const SettingsOption NoRegisterLimits{ "ROCROLLER_IGNORE_OUT_OF_REGISTERS", "Ignore register count limits for debugging purposes.", false, -1}; static inline const SettingsOption AllowUnknownInstructions{ "ROCROLLER_ALLOW_UNKNOWN_INSTRUCTIONS", "Whether to allow arbitrary instructions.", false, -1}; static inline const SettingsOption EnforceGraphConstraints{ "ROCROLLER_ENFORCE_GRAPH_CONSTRAINTS", "Whether to enforce kernel graph constraints. (Could negatively impact code gen " "performance)", false, -1}; static inline const SettingsOption AuditControlTracers{ "ROCROLLER_AUDIT_CONTROL_TRACERS", "Whether to audit predicted use of arguments and/or registers." "Could impact code gen performance.", false, -1}; static inline const SettingsOption LogGraphs{ "ROCROLLER_LOG_GRAPHS", "Whether to log graphs after each lowering stage.", true, -1}; static inline const SettingsOption LogGraphMapperConnections{ "ROCROLLER_LOG_GRAPHS_WITH_MAPPER", "Whether to include mapper connections in the per-stage graphs.", false, -1}; static inline const SettingsOption KernelAssembler{ "ROCROLLER_ASSEMBLER", "Which assembler method to use", AssemblerType::InProcess, -1}; static inline const SettingsOption SubprocessAssemblerPath{ "ROCROLLER_DEBUG_ASSEMBLER_PATH", "Path to subprocess assembler", "", -1}; static inline const std::string BitfieldName = "ROCROLLER_DEBUG"; static inline const SettingsOption F8ModeOption{ "ROCROLLER_SET_F8MODE", "F8 mode that can be either NaNoo or OCP", getDefaultF8ModeForCurrentHipDevice, -1}; static inline const SettingsOption SerializeKernelGraph{ "ROCROLLER_SERIALIZE_KERNEL_GRAPH", "Serialize kernel graph into assembly file", false, -1}; static inline const SettingsOption SerializeKernelGraphDOT{ "ROCROLLER_SERIALIZE_KERNEL_GRAPH_DOT", "Serialize kernel graph DOT into assembly file", getDefaultValueForKernelGraphDOTSerialization, -1}; static inline const SettingsOption GraphNodeLabelMaxLength{ "ROCROLLER_KGRAPH_NODE_LABEL_MAX_LENGTH", "Maximum length of KernelGraph node expression when emitting DOT", std::size_t{1000}, -1}; static inline const SettingsOption GFX1250AsicRevisionId{ "ROCROLLER_GFX1250_ASIC_REVISION_ID", "Asic revision id to use when targetting GFX1250", 1, -1}; /** * @brief Creates a help dialog for the environment variables with * their names, default values and bit-offset (if it has one). */ std::string help() const; Settings(); /** * @brief Gets the value of a SettingsOption. * * Set values for SettingsOption are stored in m_values map, * otherwise call getValue(). * * @tparam Option A SettingsOption templated by its defaultValue type. * @param opt The SettingsOption we are getting. * @return A value of type Option::Type that opt is set to. */ template typename Option::Type get(Option const& opt); /** * @brief Gets the default value of a SettingsOption. * * @tparam Option A SettingsOption templated by its defaultValue type. * @param opt The SettingsOption we are getting. * @return A value of type Option::Type is defaulted to. */ template static typename Option::Type getDefault(Option const& opt); /** * Static convenience function to get a settings value. */ template static typename Option::Type Get(Option const& opt); /** * @brief Set the value of a SettingsOption. * * Set the value of a SettingsOption. * Mismatching Option::Type and value type throws an error. * * @tparam Option A SettingsOption templated by its defaultValue type. * @tparam T The type of val. * @param opt The SettingsOption we are assigning val to. * @param val The value we are trying to assign to opt. */ template void set(Option const& opt, T const& val); /** * @brief Alias function to convert char* to std::string * * @tparam Option * @param opt * @param val */ template inline void set(Option const& opt, char const* val); private: friend rocRoller::LazySingleton; using MapReaderLock = std::shared_lock; using MapWriterLock = std::unique_lock; std::shared_mutex m_mapLock; std::map m_values; std::vector m_setBitOptions; }; } #include