|
| 1 | +#include <c10/util/Exception.h> |
| 2 | +#include <c10/util/env.h> |
| 3 | +#include <fmt/format.h> |
| 4 | +#include <cstdlib> |
| 5 | +#include <shared_mutex> |
| 6 | + |
| 7 | +namespace c10::utils { |
| 8 | + |
| 9 | +static std::shared_mutex env_mutex; |
| 10 | + |
| 11 | +// Set an environment variable. |
| 12 | +void set_env(const char* name, const char* value, bool overwrite) { |
| 13 | + std::lock_guard lk(env_mutex); |
| 14 | +#ifdef _MSC_VER |
| 15 | +#pragma warning(push) |
| 16 | +#pragma warning(disable : 4996) |
| 17 | + if (!overwrite) { |
| 18 | + // NOLINTNEXTLINE(concurrency-mt-unsafe) |
| 19 | + if (std::getenv(name) != nullptr) { |
| 20 | + return; |
| 21 | + } |
| 22 | + } |
| 23 | + auto full_env_variable = fmt::format("{}={}", name, value); |
| 24 | + // NOLINTNEXTLINE(concurrency-mt-unsafe) |
| 25 | + auto err = putenv(full_env_variable.c_str()); |
| 26 | + TORCH_INTERNAL_ASSERT( |
| 27 | + err == 0, |
| 28 | + "putenv failed for environment \"", |
| 29 | + name, |
| 30 | + "\", the error is: ", |
| 31 | + err); |
| 32 | +#pragma warning(pop) |
| 33 | +#else |
| 34 | + // NOLINTNEXTLINE(concurrency-mt-unsafe) |
| 35 | + auto err = setenv(name, value, static_cast<int>(overwrite)); |
| 36 | + TORCH_INTERNAL_ASSERT( |
| 37 | + err == 0, |
| 38 | + "setenv failed for environment \"", |
| 39 | + name, |
| 40 | + "\", the error is: ", |
| 41 | + err); |
| 42 | +#endif |
| 43 | + return; |
| 44 | +} |
| 45 | + |
| 46 | +// Reads an environment variable and returns the content if it is set |
| 47 | +std::optional<std::string> get_env(const char* name) noexcept { |
| 48 | + std::shared_lock lk(env_mutex); |
| 49 | +#ifdef _MSC_VER |
| 50 | +#pragma warning(push) |
| 51 | +#pragma warning(disable : 4996) |
| 52 | +#endif |
| 53 | + // NOLINTNEXTLINE(concurrency-mt-unsafe) |
| 54 | + auto envar = std::getenv(name); |
| 55 | +#ifdef _MSC_VER |
| 56 | +#pragma warning(pop) |
| 57 | +#endif |
| 58 | + if (envar != nullptr) { |
| 59 | + return std::string(envar); |
| 60 | + } |
| 61 | + return std::nullopt; |
| 62 | +} |
| 63 | + |
| 64 | +// Checks an environment variable is set. |
| 65 | +bool has_env(const char* name) noexcept { |
| 66 | + return get_env(name).has_value(); |
| 67 | +} |
| 68 | + |
| 69 | +// Reads an environment variable and returns |
| 70 | +// - optional<true>, if set equal to "1" |
| 71 | +// - optional<false>, if set equal to "0" |
| 72 | +// - nullopt, otherwise |
| 73 | +// |
| 74 | +// NB: |
| 75 | +// Issues a warning if the value of the environment variable is not 0 or 1. |
| 76 | +std::optional<bool> check_env(const char* name) { |
| 77 | + auto env_opt = get_env(name); |
| 78 | + if (env_opt.has_value()) { |
| 79 | + if (*env_opt == "0") { |
| 80 | + return false; |
| 81 | + } |
| 82 | + if (*env_opt == "1") { |
| 83 | + return true; |
| 84 | + } |
| 85 | + TORCH_WARN( |
| 86 | + "Ignoring invalid value for boolean flag ", |
| 87 | + name, |
| 88 | + ": ", |
| 89 | + *env_opt, |
| 90 | + "valid values are 0 or 1."); |
| 91 | + } |
| 92 | + return std::nullopt; |
| 93 | +} |
| 94 | +} // namespace c10::utils |
0 commit comments