Make NVTE tensor handle pool size configurable#3090
Conversation
Signed-off-by: hongbinl <hongbinl@nvidia.com>
for more information, see https://pre-commit.ci
Signed-off-by: hongbinl <hongbinl@nvidia.com>
for more information, see https://pre-commit.ci
|
I am not opposed to creating such a variable, but I would really like to see an example of such legitimate use which goes over this limit. Could you run the experiment that is failing for you with https://github.com/NVIDIA/TransformerEngine/blob/main/transformer_engine/common/transformer_engine.cpp#L487 set to true and send me the log of that? |
te_handle_pool_debug_fakepg_20260616-010629_2134338.pruned.log |
| constexpr const char *kWhitespace = " \t\n\r\f\v"; | ||
| const size_t first = value.find_first_not_of(kWhitespace); | ||
| const size_t last = value.find_last_not_of(kWhitespace); | ||
| NVTE_CHECK(first != std::string::npos, env_var, " must be a positive integer."); | ||
|
|
||
| size_t pool_size_mb = 0; | ||
| for (size_t i = first; i <= last; ++i) { | ||
| NVTE_CHECK(value[i] >= '0' && value[i] <= '9', env_var, " must be a positive integer, got \"", | ||
| value, "\"."); | ||
| const size_t digit = static_cast<size_t>(value[i] - '0'); | ||
| NVTE_CHECK(pool_size_mb <= (std::numeric_limits<size_t>::max() - digit) / 10, env_var, | ||
| " is too large."); | ||
| pool_size_mb = pool_size_mb * 10 + digit; | ||
| } |
There was a problem hiding this comment.
I avoided std::atoi here because it does not give us enough validation/error handling for an env var that controls an allocation size. In particular, it cannot distinguish parse failure from 0, accepts prefixes such as "50bad", returns int rather than size_t, and gives poor behavior/diagnostics for negative or overflowing inputs.
The current parser is a bit more verbose, but it intentionally enforces a full-string positive integer and checks overflow before converting to bytes, so invalid values fail with a clear NVTE_CHECK message.
If you prefer using a standard parser, I can switch this to std::strtoull/std::from_chars with explicit end-pointer/overflow checks, but I would avoid std::atoi for this case.
There was a problem hiding this comment.
Considering that it is supposed to take the value in MBs, at least some of the concerns here are not really relevant - e.g. I do not expect anybody to have a problem with int vs size_t here as the values would be < 1000. I'm fine with strtoul (again, we don't need ull here) - basically trying to make sure that the code is as understandable as possible.
There was a problem hiding this comment.
Thanks, agreed. I simplified this to use std::strtoul and kept the validation intentionally small:
- trim surrounding whitespace
- require the first non-space character to be a digit
- require strtoul to consume the full trimmed value
- require the parsed value to be > 0
- check ERANGE for overflow
|
Ok, I see why it happens. I'm ok with this PR (modulo one comment about string to integer conversion). Now, the real reason why this happens, while legitimate, is also very bad performance-wise (logic for the master weight casting to lower precision) and this should also be fixed in a separate PR. |
Signed-off-by: hongbinl <hongbinl@nvidia.com>
304bf20 to
eb12eb1
Compare
Summary
Motivation
Large model initialization paths can legitimately create more TE tensor handles than the current fixed-size pool allows, even when GPU and CPU memory are otherwise sufficient. Exposing the pool size as an environment variable avoids downstream source patches for these scale-dependent cases.
Testing