-
Notifications
You must be signed in to change notification settings - Fork 51
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
Deprecate shareRaw #1229
Deprecate shareRaw #1229
Conversation
2c5ba0a
to
19d71ca
Compare
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.
This looks good to me and as discussed, let's proceed.
Only thing I would add is another overload for contiguous containers to determineDatatype
for symmetry with storeChunk
.
@franzpoeschel pls resolve the merge conflict :) |
8449af0
to
b673b7f
Compare
Done |
b673b7f
to
4b852e2
Compare
1b21d43
to
cd3c32a
Compare
cd3c32a
to
da59c59
Compare
37d966e
to
d5547d0
Compare
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
cae3498
to
8f69473
Compare
include/openPMD/Datatype.hpp
Outdated
template <typename T> | ||
inline constexpr Datatype determineDatatypeRaw(T const *) | ||
{ | ||
return determineDatatype<T>(); | ||
} | ||
|
||
template <typename T_ContiguousContainer> | ||
inline constexpr Datatype determineDatatypeContiguous(T_ContiguousContainer &&) | ||
{ | ||
using T_ContiguousContainer_stripped = |
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.
For determineDatatype
, I tend to just use one API function name with overloads for pointers and cont. containers.
There is no lifetime question here and additional naming is not really needed, adding unnecessary API calls to learn.
What do you think?
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.
The reason I did it like this is a slight inconsistency that we would get:
determineDatatype<std::vector<float>>(); // evaluates to Datatype::VECTOR_FLOAT
determineDatatype(std::vector<float>()); // evaluates to Datatype::FLOAT, interpreting the vector as a contiguous container
As long as we don't add the following overload, this would technically work, but still be extremely confusing imo:
template <typename T>
inline constexpr Datatype determineDatatype(T)
{
// ignoring reference decaying for this example now
return determineDatatype<T>();
}
I see the appeal of not introducing new API calls left and right, but we should be aware of the possible source for confusion.
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 checked the PR again, and we could theoretically do the entire thing only with new overloads, instead of new API calls (even replace storeChunkRaw
with storeChunk
). So this is entirely a design decision:
storeChunkRaw()
: I like making it explicit that we are dealing with non-owned, raw memorydetermineDatatypeContiguous()
: Avoids confusion, as described abovedetermineDatatypeRaw()
: Would then be consistent with the change above
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 have a slide tendency to overloads, simply because it's C++ pattern (vs. C).
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.
For this case, we could make it consistently evaluate to Datatype::VECTOR_FLOAT
:
determineDatatype<std::vector<float>>();
determineDatatype(std::vector<float>());
and ask the user to call via ::value_type
or .data()
to get the fundamental type aka Datatype::FLOAT
.
determineDatatype<std::vector<float>::value_type>();
determineDatatype(std::vector<float>().data());
I think I overdid the original detection support here for STL :)
If this changes existing behavior, then let us note it in NEWS.rst
pls.
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 would maybe take your suggestion, but make it a little bit stricter:
If you want a direct translation between C++ types and our openPMD::Datatype
enum, then use determineDatatype<T>()
without argument (exactly as it is before this PR).
We provide overloads for pointer types, i.e. determineDatatype<T>(std::shared_ptr<T>)
(already exists) and determineDatatype<T>(T const *)
(new).
If a user passes a std::vector
or a std::array
, we don't even start guessing what is meant, but throw a detailed compile-time error:
Error: Passed a contiguous container type to determineDatatype<>(). [10/1843]
These types are not directly supported due to colliding semantics.
Assuming a vector object `std::vector<float> vec;`,
use one of the following alternatives:
1) If what you want is a direct openPMD::Datatype equivalent of the container
type, use:
`determineDatatype<decltype(vec)>()`
OR
`determineDatatype<std::vector<float>>()`.
The result will be `Datatype::VECTOR_FLOAT`.
2) If what you want is the openPMD::Datatype equivalent of the *contained type*,
use the raw pointer overload by:
`determineDatatype(vec.data())`
This is the variant that you likely wish to use if intending to write data
from the vector via `storeChunk()`, e.g. `storeChunk(vec, {0}, {10})`.
Corresponding implementation:
template <typename T_ContiguousContainer>
inline constexpr Datatype determineDatatype(T_ContiguousContainer &&)
{
using T_ContiguousContainer_stripped =
std::remove_reference_t<T_ContiguousContainer>;
if constexpr (auxiliary::IsContiguousContainer_v<
T_ContiguousContainer_stripped>)
{
static_assert(auxiliary::dependent_false_v<T_ContiguousContainer>, R"(
Error: Passed a contiguous container type to determineDatatype<>().
These types are not directly supported due to colliding semantics.
Assuming a vector object `std::vector<float> vec;`,
use one of the following alternatives:
1) If what you want is a direct openPMD::Datatype equivalent of the container
type, use:
`determineDatatype<decltype(vec)>()`
OR
`determineDatatype<std::vector<float>>()`.
The result will be `Datatype::VECTOR_FLOAT`.
2) If what you want is the openPMD::Datatype equivalent of the *contained type*,
use the raw pointer overload by:
`determineDatatype(vec.data())`
This is the variant that you likely wish to use if intending to write data
from the vector via `storeChunk()`, e.g. `storeChunk(vec, {0}, {10})`.
)");
}
else
{
static_assert(auxiliary::dependent_false_v<T_ContiguousContainer>, R"(
Unknown datatype passed to determineDatatype<>().
For a direct translation from C++ type to the openPMD::Datatype enum, use:
`auto determineDatatype<T>() -> Datatype`.
For detecting the contained datatpye of a pointer type (shared or raw pointer),
use either of the following overloads:
`auto determineDatatype<T>(std::shared_ptr<T>) -> Datatype` or
`auto determineDatatype<T>(T const *) -> Datatype`.
)")
}
}
This would entirely avoid any API inconsistencies, without introducing unexpected behavior where we need to guess what the user wanted.
* extent in the record component will be selected. | ||
*/ | ||
template <typename T> | ||
void loadChunk(std::shared_ptr<T> data, Offset offset, Extent extent); |
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.
Do we need a std::shared_ptr<T[]>
, too?
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.
Yeah, I forgot that in #1296. Should I open a separate PR or just add it into this one?
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.
Eh, I updated it now
* dev: (70 commits) Docs: Recommend Static Build for Superbuilds (openPMD#1325) Python 3.11 (openPMD#1323) pybind11: v2.10.1+ (openPMD#1322) Add Attribute::getOptional<T>() and use to add some more dynamic datatype conversions at read time (openPMD#1278) Mapping between ADIOS steps and openPMD iterations (openPMD#949) Deprecate shareRaw (openPMD#1229) Fix append mode double attributes (openPMD#1302) Constant scalars: Don't flush double (openPMD#1315) Remove caching cmake vars (openPMD#1313) [pre-commit.ci] pre-commit autoupdate (openPMD#1311) storeChunk: Add an overload for shared_ptr<T[]> (openPMD#1296) Fix `operationAsString` Export (openPMD#1309) ADIOS2: more fine-grained control for file endings (openPMD#1218) [pre-commit.ci] pre-commit autoupdate (openPMD#1307) Fix file existence check in parallel tests (openPMD#1303) ADIOS2: Flush to disk within a step (openPMD#1207) [pre-commit.ci] pre-commit autoupdate (openPMD#1304) [pre-commit.ci] pre-commit autoupdate (openPMD#1295) Update catch2 to v2.13.9 (openPMD#1299) [pre-commit.ci] pre-commit autoupdate (openPMD#1292) ... # Conflicts: # .github/workflows/linux.yml
Idea: Instead of
rc.storeChunk(shareRaw(ptr), …)
, have users writerc.storeChunkRaw(ptr, …)
which is a bit more transparent in what is happening. Partially resolves #1216 by introducing a clearer API that distinguishes between owned and non-owned resources.TODO
determineDatatype
)