70 "The initialisation global idx_range should be described by one of the layouts");
74 MPI_Comm_size(comm, &m_comm_size);
75 MPI_Comm_rank(comm, &rank);
77 assert(m_comm_size <= distrib_idx_range.size());
79 assert(distrib_idx_range.size() % m_comm_size == 0);
81 = m_layout_1.distribute_idx_range(global_idx_range_layout_1, m_comm_size, rank);
83 = m_layout_2.distribute_idx_range(global_idx_range_layout_2, m_comm_size, rank);
84 m_layout_1_mpi_idx_range = get_distribution(
87 m_layout_2_mpi_idx_range = get_distribution(
132 ExecSpace
const& execution_space,
133 Field<ElementType, IdxRangeOut, MemSpace> recv_field,
134 ConstField<ElementType, InIdxRange, MemSpace> send_field)
136 static_assert(!std::is_same_v<InIdxRange, IdxRangeOut>);
138 (std::is_same_v<InIdxRange, typename Layout1::discrete_domain_type>)
139 || (std::is_same_v<InIdxRange, typename Layout2::discrete_domain_type>));
141 (std::is_same_v<IdxRangeOut, typename Layout1::discrete_domain_type>)
142 || (std::is_same_v<IdxRangeOut, typename Layout2::discrete_domain_type>));
143 using OutLayout = std::conditional_t<
144 std::is_same_v<IdxRangeOut, typename Layout1::discrete_domain_type>,
147 this->transpose_to<OutLayout>(execution_space, recv_field, send_field);
167 ExecSpace
const& execution_space,
168 Field<ElementType, typename OutLayout::discrete_domain_type, MemSpace> recv_field,
169 ConstField<ElementType, InIdxRange, MemSpace> send_field)
171 using InLayout = std::conditional_t<std::is_same_v<OutLayout, Layout1>, Layout2, Layout1>;
175 static_assert((std::is_same_v<InLayout, Layout1>) || (std::is_same_v<InLayout, Layout2>));
176 static_assert((std::is_same_v<OutLayout, Layout1>) || (std::is_same_v<OutLayout, Layout2>));
177 static_assert(Kokkos::SpaceAccessibility<ExecSpace, MemSpace>::accessible);
179 static_assert(std::is_same_v<InIdxRange, typename InLayout::discrete_domain_type>);
180 using IdxRangeOut =
typename OutLayout::discrete_domain_type;
186 using dims_to_gather =
typename InLayout::distributed_type_seq;
188 using dims_to_scatter =
typename OutLayout::distributed_type_seq;
190 using gather_mpi_dims = ddcHelper::
191 apply_template_to_type_seq_t<MPIDim, typename InLayout::distributed_type_seq>;
192 using scatter_mpi_dims = ddcHelper::
193 apply_template_to_type_seq_t<MPIDim, typename OutLayout::distributed_type_seq>;
195 using input_ordered_dims = ddc::to_type_seq_t<InIdxRange>;
196 using output_ordered_dims = ddc::to_type_seq_t<IdxRangeOut>;
198 using batch_dims = ddc::type_seq_remove_t<
199 ddc::type_seq_remove_t<input_ordered_dims, dims_to_scatter>,
202 using input_mpi_idx_range_tags
203 = insert_mpi_tags_into_seq_t<scatter_mpi_dims, input_ordered_dims>;
204 using output_mpi_idx_range_tags
205 = insert_mpi_tags_into_seq_t<gather_mpi_dims, output_ordered_dims>;
208 using input_alltoall_dim_order
209 = ddc::type_seq_merge_t<scatter_mpi_dims, input_ordered_dims>;
210 using output_alltoall_dim_order
211 = ddc::type_seq_merge_t<gather_mpi_dims, input_ordered_dims>;
217 using gather_idx_range_type =
typename InLayout::distributed_sub_idx_range;
219 using scatter_idx_range_type =
typename OutLayout::distributed_sub_idx_range;
221 using batch_idx_range_type = ddc::detail::convert_type_seq_to_discrete_domain_t<batch_dims>;
222 using gather_mpi_idx_range_type
223 = ddc::detail::convert_type_seq_to_discrete_domain_t<gather_mpi_dims>;
224 using scatter_mpi_idx_range_type
225 = ddc::detail::convert_type_seq_to_discrete_domain_t<scatter_mpi_dims>;
227 using input_mpi_idx_range_type
228 = ddc::detail::convert_type_seq_to_discrete_domain_t<input_mpi_idx_range_tags>;
230 using output_mpi_idx_range_type
231 = ddc::detail::convert_type_seq_to_discrete_domain_t<output_mpi_idx_range_tags>;
233 using input_alltoall_idx_range_type
234 = ddc::detail::convert_type_seq_to_discrete_domain_t<input_alltoall_dim_order>;
236 using output_alltoall_idx_range_type
237 = ddc::detail::convert_type_seq_to_discrete_domain_t<output_alltoall_dim_order>;
244 gather_mpi_idx_range_type gather_mpi_idx_range;
245 scatter_mpi_idx_range_type scatter_mpi_idx_range;
246 if constexpr (std::is_same_v<InLayout, Layout1>) {
247 gather_mpi_idx_range = m_layout_1_mpi_idx_range;
248 scatter_mpi_idx_range = m_layout_2_mpi_idx_range;
250 gather_mpi_idx_range = m_layout_2_mpi_idx_range;
251 scatter_mpi_idx_range = m_layout_1_mpi_idx_range;
255 batch_idx_range_type batch_idx_range(get_idx_range(send_field));
256 scatter_idx_range_type scatter_idx_range(get_idx_range(recv_field));
257 gather_idx_range_type gather_idx_range(get_idx_range(send_field));
260 input_mpi_idx_range_type input_mpi_idx_range(
261 scatter_mpi_idx_range,
265 output_mpi_idx_range_type output_mpi_idx_range(
266 gather_mpi_idx_range,
270 assert(input_mpi_idx_range.size() == send_field.size());
271 assert(output_mpi_idx_range.size() == recv_field.size());
274 input_alltoall_idx_range_type input_alltoall_idx_range(input_mpi_idx_range);
275 output_alltoall_idx_range_type output_alltoall_idx_range(output_mpi_idx_range);
280 ConstField<ElementType, input_mpi_idx_range_type, MemSpace>
281 send_mpi_field(send_field.data_handle(), input_mpi_idx_range);
282 Field<ElementType, output_mpi_idx_range_type, MemSpace>
283 recv_mpi_field(recv_field.data_handle(), output_mpi_idx_range);
290 auto alltoall_send_buffer = ddcHelper::create_transpose_mirror_view_and_copy<
291 input_alltoall_idx_range_type>(execution_space, send_mpi_field);
292 auto alltoall_recv_buffer = ddcHelper::create_transpose_mirror<
293 output_alltoall_idx_range_type>(execution_space, recv_mpi_field);
298 get_field(alltoall_recv_buffer),
299 get_const_field(alltoall_send_buffer));
303 if constexpr (!ddc::is_borrowed_chunk_v<
decltype(alltoall_recv_buffer)>) {
307 get_const_field(alltoall_recv_buffer));