Skip to content

Commit 7c40994

Browse files
committed
Add an example for the named paramter namespace.
1 parent 12298bb commit 7c40994

File tree

1 file changed

+72
-52
lines changed

1 file changed

+72
-52
lines changed

examples/usage/allgatherv_example.cpp

+72-52
Original file line numberDiff line numberDiff line change
@@ -38,61 +38,81 @@ int main() {
3838
// Note, that the size of the input vector is different for each rank.
3939
std::vector<int> input(comm.rank(), comm.rank_signed());
4040

41-
{ // Basic use case; gather the inputs across all ranks to all ranks.
41+
{
42+
// we are including the namespace here to reduce verbosity
43+
using namespace kamping;
44+
{ // Basic use case; gather the inputs across all ranks to all ranks.
45+
auto const output = comm.allgatherv(send_buf(input));
46+
print_result_on_root(output, comm);
47+
}
48+
49+
{ // We can also request the number of elements received from each rank. The recv_buf will always be the first
50+
// out parameter. After that, the output parameters are ordered as they appear in the function call. KaMPIng
51+
// calls like allgatherv return a result object which can be decomposed using structured bindings (here) or
52+
// explicit extract_*() calls (see below).
53+
auto [recv_buffer, recv_counts] = comm.allgatherv(send_buf(input), recv_counts_out());
54+
}
55+
56+
{ // To re-use memory, we can provide an already allocated container to the MPI call.
57+
std::vector<int> output;
58+
// Let KaMPIng resize the recv_buffer to the correct size. Other possibilities are no_resize and grow_only.
59+
comm.allgatherv(send_buf(input), recv_buf<resize_to_fit>(output));
60+
61+
// We can also re-use already allocated containers for the other output parameters, e.g. recv_counts.
62+
std::vector<int> output_counts(comm.size());
63+
std::iota(output_counts.begin(), output_counts.end(), 0);
64+
comm.allgatherv(send_buf(input), recv_buf<resize_to_fit>(output), recv_counts(output_counts));
65+
66+
std::vector<int> displacements(comm.size());
67+
std::exclusive_scan(output_counts.begin(), output_counts.end(), displacements.begin(), 0);
68+
output.clear();
69+
70+
// In this example, we combine all of the concepts mentioned above:
71+
// - Use input as the send buffer
72+
// - Receive all elements into recv_buffer, resizing it to fit exactly the number of elements received.
73+
// - Output the number of elements received from each rank into recv_counts.
74+
// - Output the displacement of the first element received from each rank into recv_displs.
75+
comm.allgatherv(
76+
send_buf(input),
77+
recv_buf<resize_to_fit>(output),
78+
recv_counts(output_counts),
79+
recv_displs(displacements)
80+
);
81+
}
82+
83+
{ // It is also possible to use result.extract_*() calls instead of decomposing the result object using
84+
// structured bindings in order to increase readability.
85+
auto result = comm.allgatherv(send_buf(input), recv_counts_out(), recv_displs_out());
86+
auto const recv_buffer = result.extract_recv_buffer();
87+
auto const recv_counts = result.extract_recv_counts();
88+
auto const recv_displs = result.extract_recv_displs();
89+
}
90+
91+
{ // C++ views can be used to send parts of the data.
92+
input.resize(comm.rank() + 1, comm.rank_signed());
93+
94+
// Note, if you're on C++ >= 20 you can use std::span instead.
95+
comm.allgatherv(send_buf(kamping::Span(input).subspan(0, comm.rank())));
96+
97+
// Alternatively
98+
comm.allgatherv(send_buf(input), send_count(comm.rank_signed()));
99+
100+
// let's restore the input
101+
input.resize(comm.rank());
102+
}
103+
}
104+
{
105+
// if you don't want to polute your global namespace with all KaMPIng's symbols, you can just use the namespace
106+
// for named parameters
107+
using namespace kamping::params;
42108
auto const output = comm.allgatherv(send_buf(input));
43109
print_result_on_root(output, comm);
44110
}
45-
46-
{ // We can also request the number of elements received from each rank. The recv_buf will always be the first out
47-
// parameter. After that, the output parameters are ordered as they appear in the function call.
48-
// KaMPIng calls like allgatherv return a result object which can be decomposed using structured
49-
// bindings (here) or explicit extract_*() calls (see below).
50-
auto [recv_buffer, recv_counts] = comm.allgatherv(send_buf(input), recv_counts_out());
51-
}
52-
53-
{ // To re-use memory, we can provide an already allocated container to the MPI call.
54-
std::vector<int> output;
55-
// Let KaMPIng resize the recv_buffer to the correct size. Other possibilities are no_resize and grow_only.
56-
comm.allgatherv(send_buf(input), recv_buf<resize_to_fit>(output));
57-
58-
// We can also re-use already allocated containers for the other output parameters, e.g. recv_counts.
59-
std::vector<int> output_counts(comm.size());
60-
std::iota(output_counts.begin(), output_counts.end(), 0);
61-
comm.allgatherv(send_buf(input), recv_buf<resize_to_fit>(output), recv_counts(output_counts));
62-
63-
std::vector<int> displacements(comm.size());
64-
std::exclusive_scan(output_counts.begin(), output_counts.end(), displacements.begin(), 0);
65-
output.clear();
66-
67-
// In this example, we combine all of the concepts mentioned above:
68-
// - Use input as the send buffer
69-
// - Receive all elements into recv_buffer, resizing it to fit exactly the number of elements received.
70-
// - Output the number of elements received from each rank into recv_counts.
71-
// - Output the displacement of the first element received from each rank into recv_displs.
72-
comm.allgatherv(
73-
send_buf(input),
74-
recv_buf<resize_to_fit>(output),
75-
recv_counts(output_counts),
76-
recv_displs(displacements)
77-
);
78-
}
79-
80-
{ // It is also possible to use result.extract_*() calls instead of decomposing the result object using structured
81-
// bindings in order to increase readability.
82-
auto result = comm.allgatherv(send_buf(input), recv_counts_out(), recv_displs_out());
83-
auto const recv_buffer = result.extract_recv_buffer();
84-
auto const recv_counts = result.extract_recv_counts();
85-
auto const recv_displs = result.extract_recv_displs();
86-
}
87-
88-
{ // C++ views can be used to send parts of the data.
89-
input.resize(comm.rank() + 1, comm.rank_signed());
90-
91-
// Note, if you're on C++ >= 20 you can use std::span instead.
92-
comm.allgatherv(send_buf(kamping::Span(input).subspan(0, comm.rank())));
93-
94-
// Alternatively
95-
comm.allgatherv(send_buf(input), send_count(comm.rank_signed()));
111+
{
112+
// you can also use define a shorthand for the named parameter namespace, to reduce code verbosity
113+
namespace kmp = kamping::params;
114+
auto const output = comm.allgatherv(kmp::send_buf(input));
115+
print_result_on_root(output, comm);
96116
}
97117

98118
return 0;

0 commit comments

Comments
 (0)