-
Notifications
You must be signed in to change notification settings - Fork 7.1k
[core] Add a util for size literals #48638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
rynewang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but can we make at least one usage in code base to avoid dead code and to showcase? src/ray/stats/metric_defs.cc can be a good start.
src/ray/util/size_literals.h
Outdated
| constexpr unsigned long long operator""_PiB(unsigned long long sz) { | ||
| return sz * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL; | ||
| } | ||
| constexpr unsigned long long operator""_PB(unsigned long long sz) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we use long long instead of size_t
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see much difference?
unsigned long longis the largest unsigned range we could have in C++ natively- we won't have negative value here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ofc they are the same: size_t is just typedef of unsigned long long on 64bit system. However it has a clearer semantics: it represents a size, which is what all these "number of bytes" about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong preference, updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I found size_t doesn't compile
./src/ray/util/size_literals.h:22:18: error: 'constexpr size_t operator""_B(size_t)' has invalid argument list
22 | constexpr size_t operator""_B(size_t sz) { return sz; }
| ^~~~~~~~
Working version:
constexpr unsigned long long operator""_B(unsigned long long sz) { return sz; }
Non-workable version:
constexpr size_t operator""_B(size_t sz) { return sz; }
src/ray/util/size_literals.h
Outdated
|
|
||
| #include <cstdint> | ||
|
|
||
| constexpr unsigned long long operator""_PiB(unsigned long long sz) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrap everything in namespace ray::literals so users must opt-in with using
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think putting these function into a namespace is a good idea.
For example, gflag requires all flag values to placed in outmost namespace.
A typical use case is:
DEFINE_int64(some_flag_name, 15_MiB, "some flag description");
Signed-off-by: dentiny <[email protected]>
rynewang
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also since we are here - is it possible to define a class ByteSize { size_t bytes_; static operator""_KiB(...){...} } so we can be more type rich? Just discussion - did not research on how big this is.
src/ray/util/size_literals.h
Outdated
|
|
||
| constexpr unsigned long long operator""_B(unsigned long long sz) { return sz; } | ||
|
|
||
| constexpr unsigned long long operator""_KiB(unsigned long long sz) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] I'd prefer ordering as B, KB, MB,...., KiB, MiB, ....
Signed-off-by: dentiny <[email protected]>
Sure, updated one place for metrics defs. |
src/ray/util/size_literals.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] why not:
constexpr size_t operator""_PiB(long double sz) {
const long double res = sz * 1_PiB;
return static_cast<size_t>(res);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and these double-to-size_t code are so duplicated, I wonder if we can make it a macro.
// Macro to generate (long double -> size_t) literal from (size_t -> size_t)
#define CREATE_FLOAT_SIZE_LITERAL(suffix) \
constexpr size_t operator""_##suffix(long double sz) { \
return static_cast<size_t>(sz * 1_##suffix); \
}
// Using the macro to define long double -> size_t literals
CREATE_FLOAT_SIZE_LITERAL(KiB)
CREATE_FLOAT_SIZE_LITERAL(MiB)
CREATE_FLOAT_SIZE_LITERAL(GiB)
CREATE_FLOAT_SIZE_LITERAL(TiB)
CREATE_FLOAT_SIZE_LITERAL(PiB)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] why not:
constexpr size_t operator""_PiB(long double sz) {
const long double res = sz * 1_PiB;
return static_cast<size_t>(res);
}
Updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of macros.
Using macro is generally not recommended (effective C++ item-1 has a few good arguments):
- Hard to debug, easier to get wrong;
- Purely textual replacement, no compiler check (i.e. what if repeated macro definition);
- Affective, especially in header file.
I almost only use macros at error propagation (i.e. ray/util/logging.h) to save some boilerplate code for unhappy path.
For here, both implementations are just one-liner, don't see much benefit.
Emm could you please give me some examples you think it's better to have such class? |
Signed-off-by: dentiny <[email protected]>
267eeef to
3b8640d
Compare
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
Signed-off-by: dentiny <[email protected]>
As titled, I think having `MB` explicitly called out is more readable than `1024 * 1024` or `1<<20` Intended use case: ray-project#48262 (comment) Signed-off-by: dentiny <[email protected]>
As titled, I think having `MB` explicitly called out is more readable than `1024 * 1024` or `1<<20` Intended use case: ray-project#48262 (comment) Signed-off-by: dentiny <[email protected]> Signed-off-by: mohitjain2504 <[email protected]>
As titled, I think having
MBexplicitly called out is more readable than1024 * 1024or1<<20Intended use case: #48262 (comment)