Skip to content
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

Add unique_ptr overloads for storeChunk calls #1294

Merged
merged 11 commits into from
Feb 22, 2023

Conversation

franzpoeschel
Copy link
Contributor

@franzpoeschel franzpoeschel commented Jun 24, 2022

See #1216 for an explanation. The approach in this PR is to use unique_ptrs instead of relying on the refcount of shared_ptrs to make this optimization more explicit to the user.

TODO

  • Add a class OpenpmdUniquePtr that allows specifying dynamic destructors via std::function<void(T*)>, similar to std::shared_ptr. In the STL, unique_ptrs have a different type depending on their destructor, which is annoying for our use case, and the overhead of making this dynamic is negligible in our use case.
    This way, it's easily possible to e.g. pass ownership of pinned memory to openPMD and still let it correctly destroy it once used.
  • Extend the IOTask for Write_Dataset operations to accept std::variant<std::shared_ptr<void const>, OpenpmdUniquePtr<void const>> as a buffer.
    This requires some light refactoring because with this change, the IOTask is not copyable any more.
    This includes making the backends deal with both types correctly.
  • Add a storeChunk overload that accepts OpenpmdUniquePtrs
  • Actually implement the intended optimization in the ADIOS2 backend
  • testing, documentation
  • support for determineDatatype
  • Merge ADIOS2: Flush to disk within a step #1207 first
  • Check if it also works to let this be handled by Engine::close().
  • I think it might be possible to implement this in such a way that makes OpenpmdUniquePtr not leak into the public API.

@ax3l This PR should not be too much work any more, so we might as well add this to 0.15.*?

@franzpoeschel franzpoeschel added backend: ADIOS2 api: new additions to the API labels Jun 24, 2022
@lgtm-com
Copy link
Contributor

lgtm-com bot commented Jun 24, 2022

This pull request introduces 13 alerts when merging 41b5eb9 into d64365b - view on LGTM.com

new alerts:

  • 13 for Inconsistent definition of copy constructor and assignment ('Rule of Two')

@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch 3 times, most recently from 020d2dd to dd71f38 Compare July 6, 2022 19:04

if (performDataWrite)
{
// should we really do this now?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// should we really do this now?

Should we write attributes before PerformDataWrites()?

  1. Yes: Then setting another value for the attribute later won't work (see e.g SerialIOTest:)
        o.setOpenPMDextension(
            1); // this happens intentionally "late" in this test
  2. No: Then attributes would only be written very late, i.e. before EndStep().

Personally, I think if preferred_flush_target = disk is selected, then everything that can be written to disk should be, so we should leave it as it is.

Copy link
Member

@ax3l ax3l Feb 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can revisit this once we change the defaults of frontends and avoid setting defaults of attributes too early. Writing attributes after datasets are defined can help with sensible defaults, e.g., x,y,z for 3D but only x,y for 2D mesh axis labels, etc.

@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch 3 times, most recently from 01a0056 to ed1ac70 Compare July 19, 2022 12:25
@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch from ed1ac70 to 96b4721 Compare July 29, 2022 08:27
@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch 2 times, most recently from 1e73b45 to 8f3a93e Compare August 17, 2022 09:17
@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch from 8f3a93e to 28ec211 Compare October 12, 2022 09:06
@lgtm-com
Copy link
Contributor

lgtm-com bot commented Oct 12, 2022

This pull request introduces 1 alert when merging 28ec211 into 230afdd - view on LGTM.com

new alerts:

  • 1 for Inconsistent definition of copy constructor and assignment ('Rule of Two')

@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch from 28ec211 to 829eb3e Compare October 12, 2022 09:49
@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch from 829eb3e to 86025de Compare October 26, 2022 10:13
@ax3l ax3l added this to the 0.15.0 milestone Nov 3, 2022
@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch from b1e6f8b to 4acd9d1 Compare December 19, 2022 12:00
test/CoreTest.cpp Fixed Show fixed Hide fixed
@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch 3 times, most recently from a271126 to 7645264 Compare January 9, 2023 15:57
@@ -387,6 +404,9 @@ class RecordComponent : public BaseRecordComponent
*/
RecordComponent &makeEmpty(Dataset d);

void storeChunk(
auxiliary::WriteBuffer buffer, Datatype datatype, Offset o, Extent e);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private, no new API

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(could nonetheless have Doxygen block for us ;-) )

@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch from 7645264 to 15c5bef Compare January 10, 2023 13:04
template <typename T_ContiguousContainer>
inline constexpr Datatype determineDatatype(T_ContiguousContainer &&)
template <typename T>
inline constexpr Datatype determineDatatype(T &&val)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is now aware of std::unique_ptr as well as OpenpmdUniquePtr, additionally to the previous raw and shared pointers. It's now implemented via if constexpr (previously overloads). Otherwise, the API is unchanged.

Copy link
Member

@ax3l ax3l Feb 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Could be a good candidate for a C++ concept at some point.

@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch 3 times, most recently from 8ef87d9 to c685485 Compare January 16, 2023 10:18
@ax3l ax3l self-requested a review January 25, 2023 17:55
@ax3l ax3l self-assigned this Jan 25, 2023
@franzpoeschel franzpoeschel mentioned this pull request Feb 10, 2023
1 task
@franzpoeschel franzpoeschel force-pushed the topic-storeChunk-unique-ptr branch from c685485 to cfa03e5 Compare February 20, 2023 13:28
@@ -1359,3 +1362,21 @@
}
#endif
}

TEST_CASE("unique_ptr", "[core]")

Check notice

Code scanning / CodeQL

Unused static function

Static function C_A_T_C_H_T_E_S_T_50 is unreachable ([autoRegistrar51](1) must be removed at the same time)
@@ -704,9 +677,10 @@ struct OPENPMDAPI_EXPORT Parameter<Operation::DEREGISTER>
Parameter(Parameter const &) : AbstractParameter()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CodeQL: Looks like Parameter generally lacks the copy assignment operator (independent of this PR):

Parameter& operator=(const Parameter& other)

https://github.com/openPMD/openPMD-api/security/code-scanning/498

@@ -387,6 +404,9 @@ class RecordComponent : public BaseRecordComponent
*/
RecordComponent &makeEmpty(Dataset d);

void storeChunk(
auxiliary::WriteBuffer buffer, Datatype datatype, Offset o, Extent e);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(could nonetheless have Doxygen block for us ;-) )

Comment on lines +3424 to +3425
"ADIOS2 backend: Flush of late writes was requested at the "
"wrong time.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error message is not hard to understand for me :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be fair, this is an error::Internal that should only happen when there is a bug somewhere in our code. So if this error occurs, it's not really supposed to be understood by the user, but to help them report the issue in more detail.

error::Internal is always thrown in combination with a request to report it:

    Internal::Internal(std::string const &what)
        : Error(
              "Internal error: " + what +
              "\nThis is a bug. Please report at ' "
              "https://github.com/openPMD/openPMD-api/issues'.")
    {}

Copy link
Member

@ax3l ax3l Mar 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is great!

I mean for us (devs) to remember, I would extend the half sentence about the "wrong time" a bit :D

Copy link
Member

@ax3l ax3l left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This look really good to me. I have a few inline comments that can be addressed as a follow-up :)

@ax3l ax3l merged commit 9a215b2 into openPMD:dev Feb 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: new additions to the API backend: ADIOS2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants