-
Notifications
You must be signed in to change notification settings - Fork 128
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
Put/Span #1322
Comments
Alright, so last thing, to actually add something new, the Span interface returning (essentially) a pointer into an internal buffer:
I think these are two important drawbacks, but essentially I think one has to just live with them, because there is no better way (that I can think of) short of reengineering the BP3 Serializer completely to use a chain of buffers or something like that, which might be a way to prevent the 2nd issue, but I don't think it's an option any time soon. So mostly what this means is just that these issues should be documented clearly. I still have some suggestions that you could consider:
|
I swear I'm not making this up: After updating adios2 to current master, an existing user of adios2 (my particle in cell code) got broken. Simplified snippet: unsigned long length = 99;
writer.Put(var, length); This used to work. Now:
Adding a new overload to |
@germasch I remember seeing this with my local compilers, thought it's fixed. It seems is only triggered when used or by certain compilers. Thanks for reporting this, I will think of a fix. BTW, for coverage purposes, which compiler are you using? |
I believe this was with
It shouldn't be compiler dependent. The issue occurs if you're trying to write a single value with a type that is an alias to |
So I'm kinda reluctant to open yet another issue related to spans, nor do I actually much feel like going through this discussion again. Then again, it's still an open issue, so I'll try to summarize where I think we're at.
Put(Sync)
andPut(Deferred) -> PerformPuts()
mirrorMPI_Send
andMPI_Isend -> MPI_Wait
in terms of when data is ready when data can be touched by whom.If this is not what ADIOS2's API meant to express, what follows may not apply.
I think we agree on that. The current Span interface achieves those goals. It comes with caveats (I'm trying to summarize #1290 primarily -- that's a long thread, so the below won't be complete. If you feel I forgot anything important, let me know and I'll add it):
Put
, that breaks the expectation that data is ready at the time ofPut
, which is currently satisfied by the two existingPut(Sync)
andPut(Deferred)
.std::span
, butstd::span
never changesdata()
under you. Anyway, can be handled with documentation.Put
to return the buffer, but then doesn't usePut
at the time the data is ready, so implicitly, the data is ready atPerformPuts
time. To me, that's not consistent with the existing interface, and also means that there is no API to support potential overlap (the Put(Deferred) -> PerformPuts type) for engines that can use it, like InsituMPI.So what I suggested in #1290 are two changes:
PutPrealloc
(The actual name is a suggestion that could be discussed (one alternative would beGetPutBuffer
or something like this). I don't think I've found a perfect name for it, but IMO the current choice ofPut
is already taken to mean something else.Put(Sync)
andPut(Deferred)
on prealloced buffers just like on regular buffers.I had previously put forth these changes in PR #1305. (I'm not asking for it to merged here. It'd need some work and probably would conflict anyway in its old shape). It serves to demonstrate that my suggestion is quite easy straightforward to implement.
Let me try to summarize the arguments against it:
Put
can be overloaded, so everything Put-related should be calledPut
.Put(Sync)
implies data readiness.Put(Deferred)
implies data pointer readiness, but not data content readiness, which in this case happens atPerformPuts
. HencePut
doesn't actually imply data content readiness.Put
overload returns a buffer.I'm not going to try to rehash the the discussion from #1290 here. I do want to address the symmetry with a future internal-buffer access version of
Get
a little bit, but if this turns into a discussion on that interface, I think that also better be done in a separate thread:Get
side of things to have an interface that avoids a copy / duplicate memory as well.Get
is actually more complicated, because generally speaking, what's returned to the user is a view into the global array, which may well be assembled for a number of blocks that may even live in different files. Once you have to assemble things, you have to copy anyway, in which case the existing interface will do just fine.Get(Sync)
would be the right name for a function returning something Span like, with the expectation that the data will be accessible in the returned Span after theGet(Sync)
returns.Get(Deferred)
for internal buffer access, that would also return a Span, but with the expectation that the data is not yet available, but only afterPerformGets
. Same semantics as the current API. This would be useful if, for example, the data to be read actually lives on a different proc, so someMPI_Irecv()
could be started, but not yetMPI_Wait
ed for.GetRelease
(that's what I just came up with, hopefully someone else will come up with a better choice.)So what I'm getting at is that there's is no perfect symmetry between Put and Get, there already is not in the existing case. (Sure, there's Get / PerformGets and Put / PerformPuts. But the underlying semantics is actually quite different, as to when the data is ready, e.g., One takes a T*, the other a const T*, and for good reason.) An internal-buffer based Get should maintain the semantics of Get/PerformGets, but not expect to get add an additional function, just like on the Put side.
The text was updated successfully, but these errors were encountered: