env.hpp Source File

env.hpp Source File#

Composable Kernel: env.hpp Source File
utility/env.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved.
3#pragma once
4
5#ifndef CK_CODE_GEN_RTC
6
7#include <cstdlib>
8#include <cstring>
9#include <string>
10#include <string_view>
11#include <map>
12
13namespace ck {
14namespace internal {
15template <typename T>
17{
18};
19
20template <>
21struct ParseEnvVal<bool>
22{
23 static bool parse_env_var_value(const char* vp)
24 {
25 std::string value_env_str{vp};
26
27 for(auto& c : value_env_str)
28 {
29 if(std::isalpha(c) != 0)
30 {
31 c = std::tolower(static_cast<unsigned char>(c));
32 }
33 }
34
35 if(value_env_str == "disable" || value_env_str == "disabled" || value_env_str == "0" ||
36 value_env_str == "no" || value_env_str == "off" || value_env_str == "false")
37 {
38 return false;
39 }
40 else if(value_env_str == "enable" || value_env_str == "enabled" || value_env_str == "1" ||
41 value_env_str == "yes" || value_env_str == "on" || value_env_str == "true")
42 {
43 return true;
44 }
45 else
46 {
47 throw std::runtime_error("Invalid value for env variable");
48 }
49
50 return false; // shouldn't reach here
51 }
52};
53
54// Supports hexadecimals (with leading "0x"), octals (if prefix is "0") and decimals (default).
55// Returns 0 if environment variable is in wrong format (strtoull fails to parse the string).
56template <>
58{
59 static uint64_t parse_env_var_value(const char* vp) { return std::strtoull(vp, nullptr, 0); }
60};
61
62template <>
63struct ParseEnvVal<std::string>
64{
65 static std::string parse_env_var_value(const char* vp) { return std::string{vp}; }
66};
67
68template <typename T>
69struct EnvVar
70{
71 private:
72 T value{};
73 bool is_unset = true;
74
75 public:
76 const T& GetValue() const { return value; }
77
78 bool IsUnset() const { return is_unset; }
79
80 void Unset() { is_unset = true; }
81
82 void UpdateValue(const T& val)
83 {
84 is_unset = false;
85 value = val;
86 }
87
88 explicit EnvVar(const char* const name, const T& def_val)
89 {
90 // NOLINTNEXTLINE (concurrency-mt-unsafe)
91 const char* vp = std::getenv(name);
92 if(vp != nullptr) // a value was provided
93 {
94 is_unset = false;
96 }
97 else // no value provided, use default value
98 {
99 value = def_val;
100 }
101 }
102};
103} // end namespace internal
104
105// static inside function hides the variable and provides
106// thread-safety/locking
107// Used in global namespace
108#define CK_DECLARE_ENV_VAR(name, type, default_val) \
109 namespace ck::env { \
110 struct name \
111 { \
112 static_assert(std::is_same_v<name, ::ck::env::name>, \
113 "CK_DECLARE_ENV* must be used in the global namespace"); \
114 using value_type = type; \
115 static ck::internal::EnvVar<type>& Ref() \
116 { \
117 static ck::internal::EnvVar<type> var{#name, default_val}; \
118 return var; \
119 } \
120 }; \
121 }
122
123#define CK_DECLARE_ENV_VAR_BOOL(name) CK_DECLARE_ENV_VAR(name, bool, false)
124
125#define CK_DECLARE_ENV_VAR_UINT64(name) CK_DECLARE_ENV_VAR(name, uint64_t, 0)
126
127#define CK_DECLARE_ENV_VAR_STR(name) CK_DECLARE_ENV_VAR(name, std::string, "")
128
129#define CK_ENV(name) \
130 ck::env::name {}
131
132template <class EnvVar>
133inline const std::string& EnvGetString(EnvVar)
134{
135 static_assert(std::is_same_v<typename EnvVar::value_type, std::string>);
136 return EnvVar::Ref().GetValue();
137}
138
139template <class EnvVar>
140inline bool EnvIsEnabled(EnvVar)
141{
142 static_assert(std::is_same_v<typename EnvVar::value_type, bool>);
143 return !EnvVar::Ref().IsUnset() && EnvVar::Ref().GetValue();
144}
145
146template <class EnvVar>
147inline bool EnvIsDisabled(EnvVar)
148{
149 static_assert(std::is_same_v<typename EnvVar::value_type, bool>);
150 return !EnvVar::Ref().IsUnset() && !EnvVar::Ref().GetValue();
151}
152
153template <class EnvVar>
154inline uint64_t EnvValue(EnvVar)
155{
156 static_assert(std::is_same_v<typename EnvVar::value_type, uint64_t>);
157 return EnvVar::Ref().GetValue();
158}
159
160template <class EnvVar>
161inline bool EnvIsUnset(EnvVar)
162{
163 return EnvVar::Ref().IsUnset();
164}
165
166template <class EnvVar>
167void EnvUnset(EnvVar)
168{
169 EnvVar::Ref().Unset();
170}
171
173template <typename EnvVar, typename ValueType>
174void UpdateEnvVar(EnvVar, const ValueType& val)
175{
176 static_assert(std::is_same_v<typename EnvVar::value_type, ValueType>);
177 EnvVar::Ref().UpdateValue(val);
178}
179
180template <typename EnvVar>
181void UpdateEnvVar(EnvVar, const std::string_view& val)
182{
183 EnvVar::Ref().UpdateValue(
185}
186
187} // namespace ck
188
189// environment variable to enable logging:
190// export CK_LOGGING=ON or CK_LOGGING=1 or CK_LOGGING=ENABLED
191CK_DECLARE_ENV_VAR_BOOL(CK_LOGGING)
192
193#endif
Definition ck.hpp:268
bool EnvIsUnset(EnvVar)
Definition utility/env.hpp:161
const std::string & EnvGetString(EnvVar)
Definition utility/env.hpp:133
bool EnvIsEnabled(EnvVar)
Definition utility/env.hpp:140
uint64_t EnvValue(EnvVar)
Definition utility/env.hpp:154
void EnvUnset(EnvVar)
Definition utility/env.hpp:167
void UpdateEnvVar(EnvVar, const ValueType &val)
updates the cached value of an environment variable
Definition utility/env.hpp:174
bool EnvIsDisabled(EnvVar)
Definition utility/env.hpp:147
Definition allocators.h:459
STL namespace.
unsigned __int64 uint64_t
Definition stdint.h:136
EnvVar(const char *const name, const T &def_val)
Definition utility/env.hpp:88
void UpdateValue(const T &val)
Definition utility/env.hpp:82
void Unset()
Definition utility/env.hpp:80
const T & GetValue() const
Definition utility/env.hpp:76
bool IsUnset() const
Definition utility/env.hpp:78
static bool parse_env_var_value(const char *vp)
Definition utility/env.hpp:23
static std::string parse_env_var_value(const char *vp)
Definition utility/env.hpp:65
static uint64_t parse_env_var_value(const char *vp)
Definition utility/env.hpp:59
Definition utility/env.hpp:17
#define CK_DECLARE_ENV_VAR_BOOL(name)
Definition utility/env.hpp:123