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
Replace std::vector<RequestType> by RequestType in consensus algorithms. Same for AnswerType. #13722
Conversation
Same for AnswerType.
std::pair<types::global_dof_index, types::global_dof_index>, | ||
unsigned int> | ||
std::vector< | ||
std::pair<types::global_dof_index, types::global_dof_index>>, | ||
std::vector<unsigned int>> |
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.
Previously, the CA algorithms took as template arguments the element types of vectors. Now they just take the overall type as template argument, which means that it is now a vector-of-something.
send_buffer = (create_request ? create_request(rank) : | ||
std::vector<RequestType>()); | ||
send_buffer = | ||
(create_request ? Utilities::pack(create_request(rank)) : | ||
std::vector<char>()); | ||
|
||
// Post a request to send data | ||
auto ierr = MPI_Isend(send_buffer.data(), | ||
send_buffer.size() * sizeof(RequestType), | ||
MPI_BYTE, | ||
send_buffer.size(), | ||
MPI_CHAR, |
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 is one of the places where we previously sent stuff around as uninterpreted bytes. Now we properly pack up whatever object we get, and then send it around as MPI_CHAR
. It is unpacked again below.
The
|
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.
Would you have any data on the time pack
/unpack
takes compared to typical costs for using the consensus algorithms?
None beyond what @kronbichler found out a while ago, namely that we shouldn't compress data when packing. (Which I had forgotten to disable -- updated patch now pushed.) I believe I remember that @kronbichler said that the packing was not measurable at the time, but I don't recall the details. I have plans to address this in a generic way at some later point by writing |
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 think the code looks nicer this way. I guess we cannot be completely sure that the cost is really negligible, but it basically boils down to a memcpy
for those simple types, so it is likely very small for typical use cases. Do you agree @peterrum? If we really wanted we could check the step-37 benchmark. Some setup routines are quite heavy on this function, so if nothing is noticeable there (which is what I believe), we should be fine.
Just for completeness, I plan (after the release) to work on functions such as
The first would call This patch here simply makes this possible, at the cost of introducing the packing for now. |
@kronbichler Our performance tests are happily running on our cluster (I have already accumulated about 1000 artifacts or so). What about we merge and I have a look at how step 37 is doing? |
Yes, I agree. Let @peterrum make the final call. |
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 change makes sense to be able to support more types.
@bangerth What other incompatible changes are you planing? This PR breaks a lot of my projects.
This is the last change I have that is incompatible. |
The only other thing I want to do is to add the signature of a function that does not require an answer. I will for the moment implement it by just calling the other function, with more efficient implementations coming later. |
As written right now, the consensus algorithms take a
std::vector<RequestType>
/std::vector<AnswerType>
and transmit this data to other processes. However, they do this on a byte-by-byte basis, not using the MPI type mechanism. This is conceptually not great since (i) it doesn't ensure that MPI converts data types when transmitting from systems with different endianness (not generally a problem, nobody does work on systems that are heterogeneous in this way), but more importantly (ii) it essentially assumes that the bit representation of a type is all that matters. The implementation does not currently have a way to ensure that that is true, and as a consequence you can currently send things such asstd::vector<std::string>
or some such without an error -- but all you get at the other end is the same bit representation of thestd::string
object, which is not generally what you want and will contain pointers that point to random places in memory.This patch does two things:
Utilities::pack/unpack()
on the data so sent.std::vector<RequestType>
/std::vector<AnswerType>
byRequestType
/AnswerType
, that is, one can now exchange all data types via the consensus algorithms interface, not juststd::vector
objects of scalar objects.There are a couple of places in the library where the send/receive functions currently already pack non-vector objects into
std::vector<char>
arrays. This means that in those places, we currently pack/unpack twice. I will fix this in a follow-up patch, but wanted to get the basic functionality out as a stand-alone patch.I will add that there is a cost associated with packing/unpacking. I believe that that cost is acceptable given the more flexible interface.
Part of #13208.
/rebuild