mirror of
https://github.com/zebrajr/pytorch.git
synced 2026-01-15 12:15:51 +00:00
[nativert] Add utility function to convert strings into numbers. (#151467)
Summary: nativert RFC: https://github.com/zhxchen17/rfcs/blob/master/RFC-0043-torch-native-runtime.md To land the runtime into PyTorch core, we will gradually land logical parts of the code into the Github issue and get each piece properly reviewed. This diff adds a small library to convert strings into numbers which will later be used for parsing graph IR. Differential Revision: D73133034 ## Test Plan c10 unittests Pull Request resolved: https://github.com/pytorch/pytorch/pull/151467 Approved by: https://github.com/cyyever, https://github.com/albanD
This commit is contained in:
committed by
PyTorch MergeBot
parent
22ecaeb145
commit
5a66c1d921
@@ -77,4 +77,60 @@ TEST(StringUtilTest, testStrMulti) {
|
||||
}
|
||||
} // namespace test_str_multi
|
||||
|
||||
namespace test_try_to {
|
||||
TEST(tryToTest, Int64T) {
|
||||
const std::vector<std::pair<const char*, int64_t>> valid_examples = {
|
||||
{"123", 123},
|
||||
{"+456", 456},
|
||||
{"-123", -123},
|
||||
{"0x123", 291},
|
||||
{"00123", 83},
|
||||
{"000", 0},
|
||||
};
|
||||
for (const auto& [str, num] : valid_examples) {
|
||||
EXPECT_EQ(c10::tryToNumber<int64_t>(str), num);
|
||||
EXPECT_EQ(c10::tryToNumber<int64_t>(std::string{str}), num);
|
||||
}
|
||||
|
||||
const std::vector<const char*> invalid_examples = {
|
||||
"123abc",
|
||||
"123.45",
|
||||
"",
|
||||
"12345678901234567890", // overflow
|
||||
};
|
||||
for (const auto str : invalid_examples) {
|
||||
EXPECT_FALSE(c10::tryToNumber<int64_t>(str).has_value());
|
||||
EXPECT_FALSE(c10::tryToNumber<int64_t>(std::string{str}).has_value());
|
||||
}
|
||||
EXPECT_FALSE(c10::tryToNumber<int64_t>(nullptr).has_value());
|
||||
}
|
||||
|
||||
TEST(tryToTest, Double) {
|
||||
const std::vector<std::pair<const char*, double>> valid_examples = {
|
||||
{"123.45", 123.45},
|
||||
{"-123.45", -123.45},
|
||||
{"123", 123.},
|
||||
{".5", 0.5},
|
||||
{"-.02", -0.02},
|
||||
{"5e-2", 5e-2},
|
||||
{"1e+3", 1e3},
|
||||
{"0x123.45", 291.26953125},
|
||||
};
|
||||
for (const auto& [str, num] : valid_examples) {
|
||||
EXPECT_EQ(c10::tryToNumber<double>(str), num);
|
||||
EXPECT_EQ(c10::tryToNumber<double>(std::string{str}), num);
|
||||
}
|
||||
|
||||
const std::vector<const char*> invalid_examples = {
|
||||
"123abc",
|
||||
"",
|
||||
"1e309", // overflow
|
||||
};
|
||||
for (const auto str : invalid_examples) {
|
||||
EXPECT_FALSE(c10::tryToNumber<double>(str).has_value());
|
||||
EXPECT_FALSE(c10::tryToNumber<double>(std::string{str}).has_value());
|
||||
}
|
||||
EXPECT_FALSE(c10::tryToNumber<double>(nullptr).has_value());
|
||||
}
|
||||
} // namespace test_try_to
|
||||
} // namespace
|
||||
|
||||
@@ -146,4 +146,58 @@ size_t ReplaceAll(std::string& s, std::string_view from, std::string_view to) {
|
||||
return numReplaced;
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<int64_t> tryToNumber<int64_t>(const std::string& symbol) {
|
||||
return tryToNumber<int64_t>(symbol.c_str());
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<int64_t> tryToNumber<int64_t>(const char* symbol) {
|
||||
// TODO Using strtoll for portability. Consider using std::from_chars in the
|
||||
// future. According to https://libcxx.llvm.org/Status/Cxx17.html,
|
||||
// std::from_chars is not supported until clang 20. We will need MSVC to also
|
||||
// fully support std::from_chars.
|
||||
if (!symbol) {
|
||||
return std::nullopt;
|
||||
}
|
||||
char* end = nullptr;
|
||||
errno = 0;
|
||||
int64_t value = strtoll(symbol, &end, 0);
|
||||
if (errno != 0) {
|
||||
errno = 0;
|
||||
return std::nullopt;
|
||||
}
|
||||
if (*end != '\0' || end == symbol) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<double> tryToNumber<double>(const std::string& symbol) {
|
||||
return tryToNumber<double>(symbol.c_str());
|
||||
}
|
||||
|
||||
template <>
|
||||
std::optional<double> tryToNumber<double>(const char* symbol) {
|
||||
// TODO Using strtod for portability. Consider using std::from_chars in the
|
||||
// future. According to https://libcxx.llvm.org/Status/Cxx17.html,
|
||||
// std::from_chars is not supported until clang 20. We will need MSVC to also
|
||||
// fully support std::from_chars.
|
||||
if (!symbol) {
|
||||
return std::nullopt;
|
||||
}
|
||||
char* end = nullptr;
|
||||
errno = 0;
|
||||
double value = strtod(symbol, &end);
|
||||
if (errno != 0) {
|
||||
errno = 0;
|
||||
return std::nullopt;
|
||||
}
|
||||
if (*end != '\0' || end == symbol) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace c10
|
||||
|
||||
@@ -213,6 +213,31 @@ inline void printQuotedString(std::ostream& stmt, const std::string_view str) {
|
||||
stmt << "\"";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<T> tryToNumber(const char* symbol) = delete;
|
||||
template <typename T>
|
||||
std::optional<T> tryToNumber(const std::string& symbol) = delete;
|
||||
|
||||
/*
|
||||
* Convert a string to a 64 bit integer. Trailing whitespaces are not supported.
|
||||
* Similarly, integer string with trailing characters like "123abc" will be
|
||||
* rejected.
|
||||
*/
|
||||
template <>
|
||||
C10_API std::optional<int64_t> tryToNumber<int64_t>(const char* symbol);
|
||||
template <>
|
||||
C10_API std::optional<int64_t> tryToNumber<int64_t>(const std::string& symbol);
|
||||
|
||||
/*
|
||||
* Convert a string to a double. Trailing whitespaces are not supported.
|
||||
* Similarly, integer string with trailing characters like "123abc" will
|
||||
* be rejected.
|
||||
*/
|
||||
template <>
|
||||
C10_API std::optional<double> tryToNumber<double>(const char* symbol);
|
||||
template <>
|
||||
C10_API std::optional<double> tryToNumber<double>(const std::string& symbol);
|
||||
|
||||
} // namespace c10
|
||||
|
||||
C10_CLANG_DIAGNOSTIC_POP()
|
||||
|
||||
Reference in New Issue
Block a user