include/ck/utility/env.hpp Source File

include/ck/utility/env.hpp Source File#

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