@@ -38,61 +38,81 @@ int main() {
38
38
// Note, that the size of the input vector is different for each rank.
39
39
std::vector<int > input (comm.rank (), comm.rank_signed ());
40
40
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;
42
108
auto const output = comm.allgatherv (send_buf (input));
43
109
print_result_on_root (output, comm);
44
110
}
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 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);
96
116
}
97
117
98
118
return 0 ;
0 commit comments