Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
AMReX_NonLocalBC.H
Go to the documentation of this file.
1#ifndef AMREX_NONLOCAL_BC_H_
2#define AMREX_NONLOCAL_BC_H_
3#include <AMReX_Config.H>
4#include <AMReX_TypeTraits.H>
5#include <AMReX_FabArray.H>
6#include <AMReX_FArrayBox.H>
7
8namespace amrex::NonLocalBC {
9
11// [concept.IndexMapping]
12//
13
15template <typename T, typename... Args>
16using Inverse_t = decltype(std::declval<T>().Inverse(std::declval<Args>()...));
17
19template <typename T>
20struct HasInverseMemFn : IsDetectedExact<Dim3, Inverse_t, T, Dim3> {};
21
24template <class IndexMap>
26 : Conjunction<IsCallableR<Dim3, IndexMap&, const Dim3&>,
27 HasInverseMemFn<const IndexMap&>> {};
28
30// [IndexMapping.MultiBlockIndexMapping]
31//
32
44
51 [[nodiscard]] AMREX_GPU_HOST_DEVICE Dim3 operator()(Dim3 i) const noexcept {
52 int iv[3]{i.x, i.y, i.z};
53 int iv_new[3]{};
54 for (int d = 0; d < AMREX_SPACEDIM; ++d) {
55 iv_new[d] = sign[d] * (iv[permutation[d]] - offset[d]);
56 }
57 return {iv_new[0], iv_new[1], iv_new[2]};
58 }
59
66 [[nodiscard]] AMREX_GPU_HOST_DEVICE Dim3 Inverse(Dim3 i) const noexcept {
67 int iv_new[3]{i.x, i.y, i.z};
68 int iv[3]{};
69 for (int d = 0; d < AMREX_SPACEDIM; ++d) {
70 AMREX_ASSERT(sign[d] == 1 || sign[d] == -1);
71 iv[permutation[d]] = iv_new[d] * sign[d] + offset[d];
72 }
73 return {iv[0], iv[1], iv[2]};
74 }
75
76 [[nodiscard]] IndexType operator()(IndexType it) const noexcept {
77 return IndexType{IntVect{AMREX_D_DECL(it[permutation[0]], it[permutation[1]], it[permutation[2]])}};
78 }
79
80 [[nodiscard]] IndexType Inverse(IndexType it) const noexcept {
81 IntVect inverse_permutation;
82 for (int i = 0; i < AMREX_SPACEDIM; ++i) {
83 inverse_permutation[permutation[i]] = i;
84 }
85 return IndexType{IntVect{AMREX_D_DECL(it[inverse_permutation[0]], it[inverse_permutation[1]], it[inverse_permutation[2]])}};
86 }
87};
88
101template <typename DTOS>
102std::enable_if_t<IsCallableR<Dim3, DTOS, Dim3>::value, IntVect>
103Apply(DTOS const& dtos, const IntVect& iv)
104{
105 Dim3 i = dtos(iv.dim3());
106 return IntVect{AMREX_D_DECL(i.x, i.y, i.z)};
107}
108
118template <typename DTOS>
119std::enable_if_t<IsCallableR<Dim3, DTOS, Dim3>::value && !IsCallableR<IndexType, DTOS, IndexType>::value, Box>
120Image (DTOS const& dtos, const Box& box)
121{
122 IntVect mapped_smallEnd = Apply(dtos, box.smallEnd());
123 IntVect mapped_bigEnd = Apply(dtos, box.bigEnd());
124 IntVect smallEnd;
125 IntVect bigEnd;
126 for (int d = 0; d < AMREX_SPACEDIM; ++d) {
127 smallEnd[d] = std::min(mapped_smallEnd[d], mapped_bigEnd[d]);
128 bigEnd[d] = std::max(mapped_smallEnd[d], mapped_bigEnd[d]);
129 }
130 return Box{smallEnd, bigEnd, box.ixType()};
131}
132
142template <typename DTOS>
143std::enable_if_t<IsCallableR<Dim3, DTOS, Dim3>::value && IsCallableR<IndexType, DTOS, IndexType>::value, Box>
144Image (DTOS const& dtos, const Box& box)
145{
146 // "Forget" the index type mapping and invoke Image without changing the index type.
147 Box srcbox = Image([&dtos](Dim3 d) { return dtos(d); }, box);
148 // Fix the index type of the resulting box
149 srcbox.setType(dtos(box.ixType()));
150 return srcbox;
151}
152
165template <typename DTOS>
166std::enable_if_t<HasInverseMemFn<DTOS>::value, IntVect>
167ApplyInverse(DTOS const& dtos, const IntVect& iv)
168{
169 return Apply([&dtos](Dim3 i) { return dtos.Inverse(i); }, iv);
170}
171
181template <typename DTOS>
182std::enable_if_t<HasInverseMemFn<DTOS>::value && !IsCallableR<IndexType, DTOS, IndexType>::value, Box>
183InverseImage (DTOS const& dtos, const Box& box)
184{
185 return Image([&dtos](Dim3 i) { return dtos.Inverse(i); }, box);
186}
187
197template <typename DTOS>
198std::enable_if_t<HasInverseMemFn<DTOS>::value && IsCallableR<IndexType, DTOS, IndexType>::value, Box>
199InverseImage (DTOS const& dtos, const Box& box)
200{
201 return Image([&dtos](auto&& i) { return dtos.Inverse(i); }, box);
202}
203
205static_assert(IsIndexMapping<MultiBlockIndexMapping>(), // NOLINT(bugprone-throw-keyword-missing)
206 "MultiBlockIndexMapping is expected to satisfy IndexMapping");
207
209// [class.MultiBlockCommMetaData]
210//
211
218
222 template <typename DTOS,
223 typename = std::enable_if_t<IsIndexMapping<DTOS>::value>>
224 MultiBlockCommMetaData(const FabArrayBase& dst, const Box& dstbox, const FabArrayBase& src,
225 const IntVect& ngrow, DTOS const& dtos);
226
230 template <typename DTOS,
231 typename = std::enable_if_t<IsIndexMapping<DTOS>::value>>
233 const Box& dstbox, const BoxArray& srcba,
234 const DistributionMapping& srcdm, const IntVect& ngrow, DTOS const& dtos);
235
237
262 template <typename DTOS>
263 std::enable_if_t<IsIndexMapping<DTOS>::value>
264 define(const BoxArray& dstba, const DistributionMapping& dstdm, const Box& dstbox,
265 const BoxArray& srcba, const DistributionMapping& srcdm, const IntVect& ngrow,
266 DTOS const& dtos);
267};
268
270// [concept.FabProjection]
271//
272
274template <typename P, typename FAB>
276 : IsCallableR<typename FAB::value_type, P, Array4<const typename FAB::value_type>, Dim3, int>
277{};
278
280// [FabProjection.Identity]
281// [IndexMapping.Identity]
282
286struct Identity {
288 constexpr Dim3 operator()(Dim3 i) const noexcept { return i; }
290 [[nodiscard]] static constexpr Dim3 Inverse(Dim3 i) noexcept { return i; }
291
293 template <typename T>
294 constexpr T operator()(Array4<const T> array, Dim3 i, int comp = 0) const
295 noexcept(noexcept(array(i.x, i.y, i.z, comp))) {
296 return array(i.x, i.y, i.z, comp);
297 }
298
300 constexpr int operator()(int i) const noexcept { return i; }
301};
302static constexpr Identity identity{};
303
304static_assert(sizeof(Identity) == 1 );
305static_assert(std::is_trivially_default_constructible_v<Identity> );
306static_assert(std::is_trivially_copy_assignable_v<Identity> );
307static_assert(std::is_trivially_copy_constructible_v<Identity> );
308static_assert(IsIndexMapping<Identity>() ); // NOLINT(bugprone-throw-keyword-missing)
309static_assert(IsFabProjection<Identity, FArrayBox>() ); // NOLINT(bugprone-throw-keyword-missing)
310
312// [FabProjection.MapComponents]
313
320template <typename Base, typename Map = Identity> struct MapComponents {
321 static_assert(IsCallable<Base, Array4<const Real>, Dim3, int>::value,
322 "Base needs to be a callable function: (Array4<const T>, Dim3, i) -> auto.");
323
325 "Map needs to be a callable function: int -> int.");
326
327 Base base;
328 Map map;
329
330 template <typename T,
331 typename = std::enable_if_t<IsCallable<Base, Array4<const T>, Dim3, int>::value>,
332 typename = std::enable_if_t<IsCallableR<int, Map, int>::value>>
333 constexpr decltype(auto) operator()(Array4<const T> array, Dim3 i, int comp) const
334 noexcept(noexcept(base(array, i, map(comp)))) {
335 return base(array, i, map(comp));
336 }
337};
338
339static_assert(std::is_trivially_copy_assignable<MapComponents<Identity>>() ); // NOLINT(bugprone-throw-keyword-missing)
340static_assert(std::is_trivially_copy_constructible<MapComponents<Identity>>() ); // NOLINT(bugprone-throw-keyword-missing)
341static_assert(IsFabProjection<MapComponents<Identity>, FArrayBox>() ); // NOLINT(bugprone-throw-keyword-missing)
342
344// [FabProjection.MapComponents.SwapComponents]
345
351template <int I, int J> struct SwapComponents {
352 static_assert(I >= 0 && J >= 0, "I >= 0 && J >= 0");
353
357 constexpr int operator()(int i) const noexcept {
358 const int map[2] = {I, J};
359 return i == I || i == J ? map[std::size_t(i == I)] : i;
360 }
361};
362
363template <int I> struct SwapComponents<I, -1> {
364 static_assert(I >= 0, "I >= 0");
365
366 int J;
367 constexpr int operator()(int i) const noexcept {
368 const int map[2] = {I, J};
369 return i == I || i == J ? map[std::size_t(i == I)] : i;
370 }
371};
372
373template <int J> struct SwapComponents<-1, J> {
374 static_assert(J >= 0, "J >= 0");
375
376 int I;
377 constexpr int operator()(int i) const noexcept {
378 const int map[2] = {I, J};
379 return i == I || i == J ? map[std::size_t(i == I)] : i;
380 }
381};
382
383template <> struct SwapComponents<-1, -1> {
384 int I;
385 int J;
386 constexpr int operator()(int i) const noexcept {
387 const int map[2] = {I, J};
388 return i == I || i == J ? map[std::size_t(i == I)] : i;
389 }
390};
391
393
394template <int I, int J> static constexpr SwapComponents<I, J> swap_indices{};
395
396static_assert(sizeof(SwapComponents<0, 1>) == 1 );
397static_assert(sizeof(DynamicSwapComponents) == 2 * sizeof(int) );
398static_assert(sizeof(SwapComponents<0, -1>) == sizeof(int) );
399static_assert(sizeof(SwapComponents<-1, 1>) == sizeof(int) );
400static_assert(std::is_trivially_default_constructible<MapComponents<Identity, SwapComponents<0, 1>>>() ); // NOLINT(bugprone-throw-keyword-missing)
401static_assert(std::is_trivially_copy_assignable<MapComponents<Identity, SwapComponents<0, 1>>>() ); // NOLINT(bugprone-throw-keyword-missing)
402static_assert(std::is_trivially_copy_constructible<MapComponents<Identity, SwapComponents<0, 1>>>() ); // NOLINT(bugprone-throw-keyword-missing)
403static_assert(IsFabProjection<MapComponents<Identity, SwapComponents<0, 1>>, FArrayBox>() ); // NOLINT(bugprone-throw-keyword-missing)
404
405static_assert(swap_indices<0, 1>(0) == 1 );
406static_assert(swap_indices<0, 1>(1) == 0 );
407static_assert(swap_indices<0, 1>(2) == 2 );
408static_assert(DynamicSwapComponents{0, 1}(0) == 1 );
409static_assert(DynamicSwapComponents{0, 1}(1) == 0 );
410static_assert(DynamicSwapComponents{0, 1}(2) == 2 );
411
413// [class.CommData]
414// [class.CommHandler]
415
442
443#ifdef AMREX_USE_MPI
446 int n_components, std::size_t object_size, std::size_t align);
447
449void PostRecvs(CommData& recv, int mpi_tag);
450
452void PostSends(CommData& send, int mpi_tag);
453#endif
454
455
460#ifdef AMREX_USE_MPI
461 int mpi_tag{};
464#endif
465};
466
468// [concept.DataPacking]
469//
470template <typename... Args>
471using PrepareSendBuffers_t = decltype(PrepareSendBuffers(std::declval<Args>()...));
472
473template <typename... Args>
474using PrepareRecvBuffers_t = decltype(PrepareRecvBuffers(std::declval<Args>()...));
475
476template <typename... Args>
477using PackSendBuffers_t = decltype(PackSendBuffers(std::declval<Args>()...));
478
479template <typename... Args>
480using UnpackRecvBuffers_t = decltype(UnpackRecvBuffers(std::declval<Args>()...));
481
482template <typename... Args>
483using LocalCopy_t = decltype(LocalCopy(std::declval<Args>()...));
484
486#if defined(AMREX_USE_CUDA) && defined(_WIN32)
487template <typename DP, typename FAB> struct IsDataPacking : std::true_type {};
488#else
489template <typename DP, typename FAB>
492 IsDetected<LocalCopy_t, DP&, FabArray<FAB>&, const FabArray<FAB>&, const FabArrayBase::CopyComTagsContainer&>
493#ifdef AMREX_USE_MPI
494 ,IsDetected<PrepareSendBuffers_t, DP&, FabArray<FAB>&, const FabArray<FAB>&, CommData&, const FabArrayBase::MapOfCopyComTagContainers&>,
495 IsDetected<PrepareRecvBuffers_t, DP&, FabArray<FAB>&, const FabArray<FAB>&, CommData&, const FabArrayBase::MapOfCopyComTagContainers&>,
496 IsDetected<PackSendBuffers_t, DP&, const FabArray<FAB>&, CommData&>,
497 IsDetected<UnpackRecvBuffers_t, DP&, FabArray<FAB>&, CommData&>
498#endif
499 > {};
500#endif
501
502template <class FAB, class DTOS = Identity, class Proj = Identity>
503std::enable_if_t<IsBaseFab<FAB>() && IsCallableR<Dim3, DTOS, Dim3>() && IsFabProjection<Proj, FAB>()>
504local_copy_cpu (FabArray<FAB>& dest, const FabArray<FAB>& src, int dcomp, int scomp, int ncomp,
505 FabArrayBase::CopyComTagsContainer const& local_tags, DTOS const& dtos = DTOS{},
506 Proj const& proj = Proj{}) noexcept;
507
508template <class FAB, class DTOS = Identity, class Proj = Identity>
509std::enable_if_t<IsBaseFab<FAB>() && IsCallableR<Dim3, DTOS, Dim3>() && IsFabProjection<Proj, FAB>()>
510unpack_recv_buffer_cpu (FabArray<FAB>& mf, int dcomp, int ncomp, Vector<char*> const& recv_data,
511 Vector<std::size_t> const& recv_size,
513 DTOS const& dtos = DTOS{}, Proj const& proj = Proj{}) noexcept;
514
515#ifdef AMREX_USE_GPU
516template <class FAB, class DTOS = Identity, class Proj = Identity>
517std::enable_if_t<IsBaseFab<FAB>() && IsCallableR<Dim3, DTOS, Dim3>() && IsFabProjection<Proj, FAB>()>
518local_copy_gpu (FabArray<FAB>& dest, const FabArray<FAB>& src, int dcomp, int scomp, int ncomp,
519 FabArrayBase::CopyComTagsContainer const& local_tags, DTOS const& dtos = DTOS{},
520 Proj const& proj = Proj{}) noexcept;
521
522template <class FAB, class DTOS = Identity, class Proj = Identity>
523std::enable_if_t<IsBaseFab<FAB>() && IsCallableR<Dim3, DTOS, Dim3>() && IsFabProjection<Proj, FAB>()>
524unpack_recv_buffer_gpu (FabArray<FAB>& mf, int scomp, int ncomp,
525 Vector<char*> const& recv_data,
526 Vector<std::size_t> const& recv_size,
528 DTOS const& dtos = DTOS{}, Proj const& proj = Proj{});
529#endif
530
532// [DataPacking.PackComponents]
533//
534// PackComponents is the simplest data packing policy.
535// This provides us with sane default behaviour that we can use when defining new
536// data packing policies.
537
544
546template <typename FAB>
547std::enable_if_t<IsBaseFab<FAB>::value>
548LocalCopy (const PackComponents& components, FabArray<FAB>& dest, const FabArray<FAB>& src,
549 const FabArrayBase::CopyComTagsContainer& local_tags) {
550#ifdef AMREX_USE_GPU
551 if (Gpu::inLaunchRegion()) {
552 local_copy_gpu(dest, src, components.dest_component, components.src_component,
553 components.n_components, local_tags);
554 } else
555#endif
556 {
557 local_copy_cpu(dest, src, components.dest_component, components.src_component,
558 components.n_components, local_tags);
559 }
560}
561
562#ifdef AMREX_USE_MPI
564template <typename FAB>
565std::enable_if_t<IsBaseFab<FAB>::value>
566PrepareSendBuffers (const PackComponents& components, FabArray<FAB>& dest, const FabArray<FAB>& src,
568 using T = typename FAB::value_type;
569 ignore_unused(dest, src);
570 PrepareCommBuffers(comm, cctc, components.n_components, sizeof(T), alignof(T));
571}
572
574template <typename FAB>
575std::enable_if_t<IsBaseFab<FAB>::value>
576PrepareRecvBuffers (const PackComponents& components, FabArray<FAB>& dest, const FabArray<FAB>& src,
578 using T = typename FAB::value_type;
579 ignore_unused(dest, src);
580 PrepareCommBuffers(comm, cctc, components.n_components, sizeof(T), alignof(T));
581}
582
584template <typename FAB>
585std::enable_if_t<IsBaseFab<FAB>::value>
586PackSendBuffers (const PackComponents& components, const FabArray<FAB>& src, CommData& send) {
587#ifdef AMREX_USE_GPU
588 if (Gpu::inLaunchRegion()) {
590 send.data, send.size, send.cctc, send.id);
591 } else
592#endif // AMREX_USE_GPU
593 {
595 send.data, send.size, send.cctc);
596 }
597}
598
600template <typename FAB>
601std::enable_if_t<IsBaseFab<FAB>::value>
602UnpackRecvBuffers (const PackComponents& components, FabArray<FAB>& dest, const CommData& recv) {
603#ifdef AMREX_USE_GPU
604 if (Gpu::inLaunchRegion()) {
605 unpack_recv_buffer_gpu(dest, components.dest_component, components.n_components, recv.data,
606 recv.size, recv.cctc);
607 } else
608#endif // AMREX_USE_GPU
609 {
610 unpack_recv_buffer_cpu(dest, components.dest_component, components.n_components, recv.data,
611 recv.size, recv.cctc);
612 }
613}
614#endif // AMREX_USE_MPI
615
616static_assert(IsDataPacking<PackComponents, FArrayBox>(), // NOLINT(bugprone-throw-keyword-missing)
617 "PackComponents is expected to satisfy the concept DataPacking.");
618
620// [DataPacking.ApplyDtosAndProjectionOnReciever]
621//
625template <typename DTOS = Identity, typename FabProj = Identity>
627 constexpr ApplyDtosAndProjectionOnReciever() = default;
628 constexpr ApplyDtosAndProjectionOnReciever(const PackComponents& components, DTOS dtos_ = DTOS{}, FabProj proj_ = FabProj{})
629 : PackComponents(components), dtos(std::move(dtos_)), proj(std::move(proj_)) {}
630
631 DTOS dtos;
632 FabProj proj;
633
634 static_assert(IsCallableR<Dim3, DTOS, Dim3>(), "DTOS needs to be a callable: Dim3 -> Dim3");
635 static_assert(IsFabProjection<FabProj, FArrayBox>(), "FabProj needs to be at least a projection on FArrayBox.");
636};
637
639template <typename FAB, typename DTOS, typename FabProj>
640std::enable_if_t<IsBaseFab<FAB>::value>
642 const FabArray<FAB>& src, const FabArrayBase::CopyComTagsContainer& local_tags) {
643 static_assert(IsFabProjection<FabProj, FAB>(), "FabProj needs to be a projection for given FAB type.");
644#ifdef AMREX_USE_GPU
645 if (Gpu::inLaunchRegion()) {
646 local_copy_gpu(dest, src, packing.dest_component, packing.src_component,
647 packing.n_components, local_tags, packing.dtos, packing.proj);
648 } else
649#endif
650 {
651 local_copy_cpu(dest, src, packing.dest_component, packing.src_component,
652 packing.n_components, local_tags, packing.dtos, packing.proj);
653 }
654}
655
656#ifdef AMREX_USE_MPI
658template <typename FAB, typename DTOS, typename FabProj>
659std::enable_if_t<IsBaseFab<FAB>::value>
661 FabArray<FAB>& dest, const CommData& recv) {
662 // If FAB is not FArrayBox we have not checked for the correct types yet.
663 static_assert(IsFabProjection<FabProj, FAB>(), "FabProj needs to be a projection for given FAB type.");
664#ifdef AMREX_USE_GPU
665 if (Gpu::inLaunchRegion()) {
666 unpack_recv_buffer_gpu(dest, packing.dest_component, packing.n_components, recv.data,
667 recv.size, recv.cctc, packing.dtos, packing.proj);
668 } else
669#endif // AMREX_USE_GPU
670 {
671 unpack_recv_buffer_cpu(dest, packing.dest_component, packing.n_components, recv.data,
672 recv.size, recv.cctc, packing.dtos, packing.proj);
673 }
674}
675#endif // AMREX_USE_MPI
676
677static_assert(IsDataPacking<ApplyDtosAndProjectionOnReciever<>, FArrayBox>(), // NOLINT(bugprone-throw-keyword-missing)
678 "ApplyDtosAndProjectionOnReciever<> is expected to satisfy the DataPacking concept.");
679
681// [ParallelCopy_nowait]
682
683static constexpr struct NoLocalCopy {} no_local_copy{};
684static constexpr struct DoLocalCopy {} do_local_copy{};
685
707template <typename FAB, typename DataPacking,
708 typename = std::enable_if_t<IsBaseFab<FAB>::value>,
709 typename = std::enable_if_t<IsDataPacking<DataPacking, FAB>::value>>
710#ifdef AMREX_USE_MPI
713 const FabArrayBase::CommMetaData& cmd, const DataPacking& data_packing) {
714 CommHandler handler{};
715 if (ParallelContext::NProcsSub() == 1) {
716 return handler;
717 }
718 //
719 // Do this before prematurely exiting if running in parallel.
720 // Otherwise sequence numbers will not match across MPI processes.
721 //
723
724 if (cmd.m_RcvTags && !(cmd.m_RcvTags->empty())) {
725 PrepareRecvBuffers(data_packing, dest, src, handler.recv, *cmd.m_RcvTags);
726 PostRecvs(handler.recv, handler.mpi_tag);
727 }
728
729 if (cmd.m_SndTags && !(cmd.m_SndTags->empty())) {
730 PrepareSendBuffers(data_packing, dest, src, handler.send, *cmd.m_SndTags);
731 PackSendBuffers(data_packing, src, handler.send);
732 PostSends(handler.send, handler.mpi_tag);
733 }
734 return handler;
735}
736#else
737CommHandler ParallelCopy_nowait (NoLocalCopy, FabArray<FAB>&, const FabArray<FAB>&,
738 const FabArrayBase::CommMetaData&, const DataPacking&) {
739 return CommHandler{};
740}
741#endif
742
764template <typename FAB, typename DataPacking,
765 typename = std::enable_if_t<IsBaseFab<FAB>::value>,
766 typename = std::enable_if_t<IsDataPacking<DataPacking, FAB>::value>>
767#ifdef AMREX_USE_MPI
769#endif
770CommHandler
772 const FabArrayBase::CommMetaData& cmd, const DataPacking& data_packing) {
773 CommHandler comm = ParallelCopy_nowait(no_local_copy, dest, src, cmd, data_packing);
774 // Eagerly do the local work and hope for some overlap with communication
775 if (cmd.m_LocTags && !cmd.m_LocTags->empty()) {
776 LocalCopy(data_packing, dest, src, *cmd.m_LocTags);
777 }
778 return comm;
779}
781// [ParallelCopy_finish]
782
801template <typename FAB, typename DataPacking>
802std::enable_if_t<IsBaseFab<FAB>() && IsDataPacking<DataPacking, FAB>()>
803#ifdef AMREX_USE_MPI
805 const FabArrayBase::CommMetaData& cmd, const DataPacking& data_packing) {
806 // If any FabArray is empty we have nothing to do.
807 if (dest.empty()) {
808 return;
809 }
810 // Return if nothing do
811 if (ParallelContext::NProcsSub() == 1) {
812 return;
813 }
814 // Unpack receives
815 if (cmd.m_RcvTags && !(cmd.m_RcvTags->empty())) {
817#ifdef AMREX_DEBUG
818 if (!CheckRcvStats(handler.recv.stats, handler.recv.size, handler.mpi_tag)) {
819 amrex::Abort("NonLocalPC::ParallelCopy_finish failed with wrong message size");
820 }
821#endif
822 UnpackRecvBuffers(data_packing, dest, handler.recv);
823 }
824
825 // Wait for all sends to be done
826 if (cmd.m_SndTags && !(cmd.m_SndTags->empty())) {
828 }
829}
830#else
831ParallelCopy_finish (FabArray<FAB>&, CommHandler, const FabArrayBase::CommMetaData&, const DataPacking&) {}
832#endif
833
853template <typename FAB, typename DataPacking>
854std::enable_if_t<IsBaseFab<FAB>() && IsDataPacking<DataPacking, FAB>()>
856 const FabArrayBase::CommMetaData& cmd, const DataPacking& data_packing) {
857 // Eagerly do the local work and hope for some overlap with communication
858 if (cmd.m_LocTags && !cmd.m_LocTags->empty()) {
859 LocalCopy(data_packing, dest, src, *cmd.m_LocTags);
860 }
861 ParallelCopy_finish(dest, std::move(handler), cmd, data_packing); // NOLINT
862}
863
888template <typename FAB, typename DTOS = Identity, typename Proj = Identity>
889std::enable_if_t<IsBaseFab<FAB>() && IsCallableR<Dim3, DTOS, Dim3>() && IsFabProjection<Proj, FAB>()>
891 SrcComp srccomp, DestComp destcomp, NumComps numcomp, DTOS const& dtos = DTOS{}, Proj const& proj = Proj{}) {
892 PackComponents components{};
893 components.dest_component = destcomp.i;
894 components.src_component = srccomp.i;
895 components.n_components = numcomp.n;
896#if defined(__GNUC__) && !defined(__clang__)
897#pragma GCC diagnostic push
898#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
899#endif
900 ApplyDtosAndProjectionOnReciever<DTOS, Proj> packing{components, dtos, proj};
901 CommHandler handler = ParallelCopy_nowait(dest, src, cmd, packing);
902 ParallelCopy_finish(dest, std::move(handler), cmd, packing); // NOLINT
903#if defined(__GNUC__) && !defined(__clang__)
904#pragma GCC diagnostic pop
905#endif
906}
907
932template <typename FAB, typename DTOS = Identity, typename Proj = Identity>
933std::enable_if_t<IsBaseFab<FAB>() && IsCallableR<Dim3, DTOS, Dim3>() && IsFabProjection<Proj, FAB>()>
935 int srccomp, int destcomp, int numcomp, DTOS const& dtos = DTOS{}, Proj const& proj = Proj{}) {
936 ParallelCopy(dest, src, cmd, SrcComp(srccomp), DestComp(destcomp), NumComps(numcomp), dtos, proj);
937}
938
968template <typename FAB, typename DTOS = Identity, typename Proj = Identity>
969std::enable_if_t<IsBaseFab<FAB>() && IsIndexMapping<DTOS>() && IsFabProjection<Proj, FAB>(),
970MultiBlockCommMetaData>
971ParallelCopy (FabArray<FAB>& dest, const Box& destbox, const FabArray<FAB>& src, SrcComp srccomp,
972 DestComp destcomp, NumComps numcomp, const IntVect& ngrow, DTOS const& dtos = DTOS{}, Proj const& proj = Proj{}) {
973 MultiBlockCommMetaData cmd(dest, destbox, src, ngrow, dtos);
974 ParallelCopy(dest, src, cmd, srccomp, destcomp, numcomp, dtos, proj);
975 return cmd;
976}
977
1007template <typename FAB, typename DTOS = Identity, typename Proj = Identity>
1008std::enable_if_t<IsBaseFab<FAB>() && IsIndexMapping<DTOS>() && IsFabProjection<Proj, FAB>(),
1009MultiBlockCommMetaData>
1010ParallelCopy (FabArray<FAB>& dest, const Box& destbox, const FabArray<FAB>& src, int srccomp,
1011 int destcomp, int numcomp, const IntVect& ngrow, DTOS const& dtos = DTOS{}, Proj const& proj = Proj{}) {
1012 return ParallelCopy(dest, destbox, src, SrcComp(srccomp), DestComp(destcomp), NumComps(numcomp), ngrow, dtos, proj);
1013}
1014
1015// Rotate90 fills the lo-x and lo-y boundary regions by rotating the data
1016// around (x=0,y=0) by 90 degrees in either direction. It also fills the
1017// corner of lo-x and lo-y boundary region by rotating the data by 180
1018// degrees.
1019
1020template <class FAB>
1021std::enable_if_t<IsBaseFab<FAB>::value>
1022Rotate90 (FabArray<FAB>& mf, int scomp, int ncomp, IntVect const& nghost, Box const& domain);
1023
1024template <class FAB>
1025std::enable_if_t<IsBaseFab<FAB>::value>
1026Rotate90 (FabArray<FAB>& mf, Box const& domain);
1027
1028// Rotate180 fills the lo-x boundary by rotating the data around
1029// (x=0,y=L_y/2) by 180 degrees.
1030
1031template <class FAB>
1032std::enable_if_t<IsBaseFab<FAB>::value>
1033Rotate180 (FabArray<FAB>& mf, int scomp, int ncomp, IntVect const& nghost, Box const& domain);
1034
1035template <class FAB>
1036std::enable_if_t<IsBaseFab<FAB>::value>
1037Rotate180 (FabArray<FAB>& mf, Box const& domain);
1038
1039// Fill the polar boundaries of the spherical coordinates (theta, phi, r).
1040// The lo-x boundary is filled with f(-x,y) = f(x,mod(y+pi,2*pi)), and
1041// the hi-x boundary is filled with f(pi+x,y) = f(pi-x,mod(y+pi,2*pi)).
1042
1043template <class FAB>
1044std::enable_if_t<IsBaseFab<FAB>::value>
1045FillPolar (FabArray<FAB>& mf, int scomp, int ncomp, IntVect const& nghost, Box const& domain);
1046
1047template <class FAB>
1048std::enable_if_t<IsBaseFab<FAB>::value>
1049FillPolar (FabArray<FAB>& mf, Box const& domain);
1050
1087template <typename FAB, typename DTOS, typename Proj = Identity>
1088[[nodiscard]]
1089std::enable_if_t<IsBaseFab<FAB>() &&
1094 int scomp, int ncomp, DTOS const& dtos,
1095 Proj const& proj = Proj{});
1096
1132template <typename FAB, typename DTOS, typename Proj = Identity>
1133std::enable_if_t<IsBaseFab<FAB>() &&
1135 IsFabProjection<Proj,FAB>()>
1138 int scomp, int ncomp, DTOS const& dtos,
1139 Proj const& proj = Proj{});
1140
1172template <typename FAB, typename DTOS, typename Proj = Identity>
1173std::enable_if_t<IsBaseFab<FAB>() &&
1175 IsFabProjection<Proj,FAB>()>
1177 int scomp, int ncomp, DTOS const& dtos, Proj const& proj = Proj{})
1178{
1179 BL_PROFILE("FillBoundary(cmd)");
1180 auto handler = FillBoundary_nowait(mf, cmd, scomp, ncomp, dtos, proj);
1181 FillBoundary_finish(std::move(handler), mf, cmd, scomp, ncomp, dtos, proj);
1182}
1183
1198template <typename FAB, typename DTOS>
1199[[nodiscard]]
1200std::enable_if_t<IsBaseFab<FAB>() && IsCallableR<Dim3,DTOS,Dim3>(),
1201 FabArrayBase::CommMetaData>
1203 Geometry const& geom, DTOS const& dtos);
1204
1205}
1206
1207#include <AMReX_NonLocalBCImpl.H>
1208
1209namespace amrex {
1214 using NonLocalBC::SphThetaPhiRIndexMapping;
1215 using NonLocalBC::SphThetaPhiRComponentMapping;
1222}
1223
1224#endif
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_NODISCARD
Definition AMReX_Extension.H:251
std::enable_if_t< IsFabArray< MF >::value > FillBoundary(Vector< MF * > const &mf, Vector< int > const &scomp, Vector< int > const &ncomp, Vector< IntVect > const &nghost, Vector< Periodicity > const &period, Vector< int > const &cross={})
Definition AMReX_FabArrayCommI.H:1036
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
A collection of Boxes stored in an Array.
Definition AMReX_BoxArray.H:551
__host__ __device__ const IntVectND< dim > & bigEnd() const &noexcept
Get the bigend.
Definition AMReX_Box.H:119
__host__ __device__ IndexTypeND< dim > ixType() const noexcept
Returns the indexing type.
Definition AMReX_Box.H:130
__host__ __device__ BoxND & setType(const IndexTypeND< dim > &t) noexcept
Set indexing type.
Definition AMReX_Box.H:495
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Get the smallend of the BoxND.
Definition AMReX_Box.H:108
Calculates the distribution of FABs to MPI processes.
Definition AMReX_DistributionMapping.H:41
A Fortran Array of REALs.
Definition AMReX_FArrayBox.H:229
Base class for FabArray.
Definition AMReX_FabArrayBase.H:42
CopyComTag::CopyComTagsContainer CopyComTagsContainer
Definition AMReX_FabArrayBase.H:220
CopyComTag::MapOfCopyComTagContainers MapOfCopyComTagContainers
Definition AMReX_FabArrayBase.H:221
bool empty() const noexcept
Definition AMReX_FabArrayBase.H:89
An Array of FortranArrayBox(FAB)-like Objects.
Definition AMReX_FabArray.H:345
static void pack_send_buffer_gpu(FabArray< FAB > const &src, int scomp, int ncomp, Vector< char * > const &send_data, Vector< std::size_t > const &send_size, Vector< const CopyComTagsContainer * > const &send_cctc, std::uint64_t id)
static void pack_send_buffer_cpu(FabArray< FAB > const &src, int scomp, int ncomp, Vector< char * > const &send_data, Vector< std::size_t > const &send_size, Vector< const CopyComTagsContainer * > const &send_cctc)
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:73
__host__ __device__ Dim3 dim3() const noexcept
Definition AMReX_IntVect.H:170
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:92
Definition AMReX_NonLocalBC.cpp:3
decltype(UnpackRecvBuffers(std::declval< Args >()...)) UnpackRecvBuffers_t
Definition AMReX_NonLocalBC.H:480
std::enable_if_t< IsCallableR< Dim3, DTOS, Dim3 >::value, IntVect > Apply(DTOS const &dtos, const IntVect &iv)
Applies the Dim3 to Dim3 mapping onto IntVects.
Definition AMReX_NonLocalBC.H:103
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >() &&IsFabProjection< Proj, FAB >()> unpack_recv_buffer_cpu(FabArray< FAB > &mf, int dcomp, int ncomp, Vector< char * > const &recv_data, Vector< std::size_t > const &recv_size, Vector< FabArrayBase::CopyComTagsContainer const * > const &recv_cctc, DTOS const &dtos=DTOS{}, Proj const &proj=Proj{}) noexcept
decltype(std::declval< T >().Inverse(std::declval< Args >()...)) Inverse_t
Return type of an InverseImage class member function.
Definition AMReX_NonLocalBC.H:16
std::enable_if_t< IsBaseFab< FAB >::value > Rotate90(FabArray< FAB > &mf, int scomp, int ncomp, IntVect const &nghost, Box const &domain)
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >() &&IsFabProjection< Proj, FAB >()> FillBoundary(FabArray< FAB > &mf, const FabArrayBase::CommMetaData &cmd, int scomp, int ncomp, DTOS const &dtos, Proj const &proj=Proj{})
Fill ghost cells for FabArray/MultiFab.
Definition AMReX_NonLocalBC.H:1176
decltype(PackSendBuffers(std::declval< Args >()...)) PackSendBuffers_t
Definition AMReX_NonLocalBC.H:477
void PrepareCommBuffers(CommData &comm, const FabArrayBase::MapOfCopyComTagContainers &cctc, int n_components, std::size_t object_size, std::size_t align)
Fill all class member variables of comm but the request and the stats vector.
Definition AMReX_NonLocalBC.cpp:41
std::enable_if_t< IsBaseFab< FAB >::value > Rotate180(FabArray< FAB > &mf, int scomp, int ncomp, IntVect const &nghost, Box const &domain)
std::enable_if_t< IsCallableR< Dim3, DTOS, Dim3 >::value &&!IsCallableR< IndexType, DTOS, IndexType >::value, Box > Image(DTOS const &dtos, const Box &box)
Applies the Dim3 to Dim3 mapping onto Boxes but does not change the index type.
Definition AMReX_NonLocalBC.H:120
std::enable_if_t< IsBaseFab< FAB >::value > LocalCopy(const PackComponents &components, FabArray< FAB > &dest, const FabArray< FAB > &src, const FabArrayBase::CopyComTagsContainer &local_tags)
Dispatch local copies to the default behaviour that knows no DTOS nor projection.
Definition AMReX_NonLocalBC.H:548
decltype(LocalCopy(std::declval< Args >()...)) LocalCopy_t
Definition AMReX_NonLocalBC.H:483
std::enable_if_t< HasInverseMemFn< DTOS >::value, IntVect > ApplyInverse(DTOS const &dtos, const IntVect &iv)
Applies the Dim3 to Dim3 invserse mapping onto IntVects.
Definition AMReX_NonLocalBC.H:167
void PostSends(CommData &send, int mpi_tag)
Initiate all sends with MPI_Isend calls associated with tag mpi_tag.
Definition AMReX_NonLocalBC.cpp:123
static constexpr SwapComponents< I, J > swap_indices
Definition AMReX_NonLocalBC.H:394
void PostRecvs(CommData &recv, int mpi_tag)
Initiate all recvieves with MPI_Irecv calls associated with tag mpi_tag.
Definition AMReX_NonLocalBC.cpp:107
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >(), FabArrayBase::CommMetaData > makeFillBoundaryMetaData(FabArray< FAB > &mf, IntVect const &nghost, Geometry const &geom, DTOS const &dtos)
Make metadata for FillBoundary.
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >() &&IsFabProjection< Proj, FAB >()> local_copy_gpu(FabArray< FAB > &dest, const FabArray< FAB > &src, int dcomp, int scomp, int ncomp, FabArrayBase::CopyComTagsContainer const &local_tags, DTOS const &dtos=DTOS{}, Proj const &proj=Proj{}) noexcept
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >() &&IsFabProjection< Proj, FAB >()> FillBoundary_finish(CommHandler handler, FabArray< FAB > &mf, const FabArrayBase::CommMetaData &cmd, int scomp, int ncomp, DTOS const &dtos, Proj const &proj=Proj{})
Finish communication started by FillBoundary_nowait.
std::enable_if_t< IsBaseFab< FAB >::value > FillPolar(FabArray< FAB > &mf, int scomp, int ncomp, IntVect const &nghost, Box const &domain)
static constexpr struct amrex::NonLocalBC::DoLocalCopy do_local_copy
decltype(PrepareSendBuffers(std::declval< Args >()...)) PrepareSendBuffers_t
Definition AMReX_NonLocalBC.H:471
std::enable_if_t< HasInverseMemFn< DTOS >::value &&!IsCallableR< IndexType, DTOS, IndexType >::value, Box > InverseImage(DTOS const &dtos, const Box &box)
Applies the inverse Dim3 to Dim3 mapping onto Boxes without changing the index type.
Definition AMReX_NonLocalBC.H:183
template MultiBlockCommMetaData ParallelCopy(FabArray< FArrayBox > &dest, const Box &destbox, const FabArray< FArrayBox > &src, int destcomp, int srccomp, int numcomp, const IntVect &ngrow, MultiBlockIndexMapping const &, Identity const &)
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >() &&IsFabProjection< Proj, FAB >()> local_copy_cpu(FabArray< FAB > &dest, const FabArray< FAB > &src, int dcomp, int scomp, int ncomp, FabArrayBase::CopyComTagsContainer const &local_tags, DTOS const &dtos=DTOS{}, Proj const &proj=Proj{}) noexcept
std::enable_if_t< IsBaseFab< FAB >::value > PrepareRecvBuffers(const PackComponents &components, FabArray< FAB > &dest, const FabArray< FAB > &src, CommData &comm, const FabArrayBase::MapOfCopyComTagContainers &cctc)
Calls PrepareComBuffers.
Definition AMReX_NonLocalBC.H:576
static constexpr Identity identity
Definition AMReX_NonLocalBC.H:302
decltype(PrepareRecvBuffers(std::declval< Args >()...)) PrepareRecvBuffers_t
Definition AMReX_NonLocalBC.H:474
CommHandler ParallelCopy_nowait(NoLocalCopy, FabArray< FAB > &dest, const FabArray< FAB > &src, const FabArrayBase::CommMetaData &cmd, const DataPacking &data_packing)
Definition AMReX_NonLocalBC.H:712
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >() &&IsFabProjection< Proj, FAB >(), CommHandler > FillBoundary_nowait(FabArray< FAB > &mf, const FabArrayBase::CommMetaData &cmd, int scomp, int ncomp, DTOS const &dtos, Proj const &proj=Proj{})
Start communication to fill boundary.
std::enable_if_t< IsBaseFab< FAB >::value > UnpackRecvBuffers(const PackComponents &components, FabArray< FAB > &dest, const CommData &recv)
De-serializes FAB data without any knowledge of a DTOS nor a projection.
Definition AMReX_NonLocalBC.H:602
std::enable_if_t< IsBaseFab< FAB >::value > PrepareSendBuffers(const PackComponents &components, FabArray< FAB > &dest, const FabArray< FAB > &src, CommData &comm, const FabArrayBase::MapOfCopyComTagContainers &cctc)
Calls PrepareComBuffers.
Definition AMReX_NonLocalBC.H:566
std::enable_if_t< IsBaseFab< FAB >() &&IsCallableR< Dim3, DTOS, Dim3 >() &&IsFabProjection< Proj, FAB >()> unpack_recv_buffer_gpu(FabArray< FAB > &mf, int scomp, int ncomp, Vector< char * > const &recv_data, Vector< std::size_t > const &recv_size, Vector< FabArrayBase::CopyComTagsContainer const * > const &recv_cctc, DTOS const &dtos=DTOS{}, Proj const &proj=Proj{})
static constexpr struct amrex::NonLocalBC::NoLocalCopy no_local_copy
SwapComponents<-1, -1 > DynamicSwapComponents
Definition AMReX_NonLocalBC.H:392
std::enable_if_t< IsBaseFab< FAB >::value > PackSendBuffers(const PackComponents &components, const FabArray< FAB > &src, CommData &send)
Serializes FAB data without any knowledge of a DTOS nor a projection.
Definition AMReX_NonLocalBC.H:586
std::enable_if_t< IsBaseFab< FAB >() &&IsDataPacking< DataPacking, FAB >()> ParallelCopy_finish(FabArray< FAB > &dest, CommHandler handler, const FabArrayBase::CommMetaData &cmd, const DataPacking &data_packing)
Definition AMReX_NonLocalBC.H:804
int NProcsSub() noexcept
number of ranks in current frame
Definition AMReX_ParallelContext.H:74
void Waitall(Vector< MPI_Request > &, Vector< MPI_Status > &)
Definition AMReX_ParallelDescriptor.cpp:1304
int SeqNum() noexcept
Returns sequential message sequence numbers, usually used as tags for send/recv.
Definition AMReX_ParallelDescriptor.H:613
Definition AMReX_Amr.cpp:49
__host__ __device__ void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:138
std::unique_ptr< char, TheFaArenaDeleter > TheFaArenaPointer
Definition AMReX_FabArray.H:104
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
void ParallelCopy(MF &dst, MF const &src, int scomp, int dcomp, int ncomp, IntVect const &ng_src=IntVect(0), IntVect const &ng_dst=IntVect(0), Periodicity const &period=Periodicity::NonPeriodic())
dst = src w/ MPI communication
Definition AMReX_FabArrayUtility.H:1967
std::is_same< Expected, Detected_t< Op, Args... > > IsDetectedExact
Definition AMReX_TypeTraits.H:189
Definition AMReX_Array4.H:61
Logical traits let us combine multiple type requirements in one enable_if_t clause.
Definition AMReX_TypeTraits.H:233
Definition AMReX_BaseFab.H:72
int i
Definition AMReX_BaseFab.H:75
Definition AMReX_Dim3.H:12
int x
Definition AMReX_Dim3.H:12
int z
Definition AMReX_Dim3.H:12
int y
Definition AMReX_Dim3.H:12
Definition AMReX_FabArrayBase.H:472
std::unique_ptr< MapOfCopyComTagContainers > m_RcvTags
Definition AMReX_FabArrayBase.H:478
std::unique_ptr< MapOfCopyComTagContainers > m_SndTags
Definition AMReX_FabArrayBase.H:477
std::unique_ptr< CopyComTagsContainer > m_LocTags
Definition AMReX_FabArrayBase.H:476
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:215
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:209
This class specializes behaviour on local copies and unpacking receive buffers.
Definition AMReX_NonLocalBC.H:626
constexpr ApplyDtosAndProjectionOnReciever(const PackComponents &components, DTOS dtos_=DTOS{}, FabProj proj_=FabProj{})
Definition AMReX_NonLocalBC.H:628
FabProj proj
Definition AMReX_NonLocalBC.H:632
DTOS dtos
Definition AMReX_NonLocalBC.H:631
This class holds data buffers for either immediate MPI send or recv calls.
Definition AMReX_NonLocalBC.H:421
Vector< std::size_t > size
The size in bytes for each data transaction.
Definition AMReX_NonLocalBC.H:432
Vector< char * > data
Pointers to the_data that can be used for each single data transaction.
Definition AMReX_NonLocalBC.H:428
Vector< const FabArrayBase::CopyComTagsContainer * > cctc
For each request the copy comm tags for the corresponding data FABs.
Definition AMReX_NonLocalBC.H:438
Vector< MPI_Status > stats
For each request the corresponding MPI_status, used for debugging.
Definition AMReX_NonLocalBC.H:436
Vector< MPI_Request > request
The associated MPI_Request for each data transaction.
Definition AMReX_NonLocalBC.H:434
TheFaArenaPointer the_data
Holds 'em all in one data pointer.
Definition AMReX_NonLocalBC.H:424
std::uint64_t id
Definition AMReX_NonLocalBC.H:439
Vector< int > rank
Stores MPI ranks. For recvs it is the 'from' rank and for sends it is the 'to' rank.
Definition AMReX_NonLocalBC.H:426
Vector< std::size_t > offset
All offsets of data in the_data.
Definition AMReX_NonLocalBC.H:430
This class stores both recv and send buffers with an associated MPI tag.
Definition AMReX_NonLocalBC.H:459
CommData send
Definition AMReX_NonLocalBC.H:463
int mpi_tag
Definition AMReX_NonLocalBC.H:461
CommData recv
Definition AMReX_NonLocalBC.H:462
Definition AMReX_NonLocalBC.H:684
Type trait that tests if T has an InverseImage class member function.
Definition AMReX_NonLocalBC.H:20
This class acts as a default no-op operator.
Definition AMReX_NonLocalBC.H:286
constexpr Dim3 operator()(Dim3 i) const noexcept
The identity function for Dim3.
Definition AMReX_NonLocalBC.H:288
constexpr T operator()(Array4< const T > array, Dim3 i, int comp=0) const noexcept(noexcept(array(i.x, i.y, i.z, comp)))
Definition AMReX_NonLocalBC.H:294
constexpr int operator()(int i) const noexcept
The identity for int.
Definition AMReX_NonLocalBC.H:300
static constexpr Dim3 Inverse(Dim3 i) noexcept
The identity function for Dim3.
Definition AMReX_NonLocalBC.H:290
This type trait tests if a given type DP satisfies the DataPacking concept for type FAB.
Definition AMReX_NonLocalBC.H:499
This type trait tests if a type P is a projection for FAB.
Definition AMReX_NonLocalBC.H:277
Tests if a given type IndexMap is usable as an index mapping between two index based coordinate syste...
Definition AMReX_NonLocalBC.H:27
This class takes a projection and a component map and combines them to form a new projection.
Definition AMReX_NonLocalBC.H:320
Base base
Definition AMReX_NonLocalBC.H:327
Map map
Definition AMReX_NonLocalBC.H:328
This is the index mapping based on the DTOS MultiBlockDestToSrc.
Definition AMReX_NonLocalBC.H:216
MultiBlockCommMetaData(const FabArrayBase &dst, const Box &dstbox, const FabArrayBase &src, const IntVect &ngrow, DTOS const &dtos)
Build global meta data by calling the define() member function.
std::enable_if_t< IsIndexMapping< DTOS >::value > define(const BoxArray &dstba, const DistributionMapping &dstdm, const Box &dstbox, const BoxArray &srcba, const DistributionMapping &srcdm, const IntVect &ngrow, DTOS const &dtos)
Build global meta data that is being used to identify send and recv dependencies in communication rou...
MultiBlockCommMetaData(const BoxArray &dstba, const DistributionMapping &dstdm, const Box &dstbox, const BoxArray &srcba, const DistributionMapping &srcdm, const IntVect &ngrow, DTOS const &dtos)
Build global meta data by calling the define() member function.
This struct describes an affine index transformation for two coordinate systems.
Definition AMReX_NonLocalBC.H:37
IndexType operator()(IndexType it) const noexcept
Definition AMReX_NonLocalBC.H:76
IntVect sign
A vector of 1 and -1 describing the orientation in each component.
Definition AMReX_NonLocalBC.H:43
__host__ __device__ Dim3 operator()(Dim3 i) const noexcept
Applies this mapping on the index from destination space and returns an index in the source space.
Definition AMReX_NonLocalBC.H:51
__host__ __device__ Dim3 Inverse(Dim3 i) const noexcept
The inverse function is given by rearringing all above terms.
Definition AMReX_NonLocalBC.H:66
IntVect offset
The offset in the source index space.
Definition AMReX_NonLocalBC.H:41
IntVect permutation
This vector needs to be a valid permutation.
Definition AMReX_NonLocalBC.H:39
IndexType Inverse(IndexType it) const noexcept
Definition AMReX_NonLocalBC.H:80
Definition AMReX_NonLocalBC.H:683
Contains information about which components take part of the data transaction.
Definition AMReX_NonLocalBC.H:539
int dest_component
Definition AMReX_NonLocalBC.H:540
int src_component
Definition AMReX_NonLocalBC.H:541
int n_components
Definition AMReX_NonLocalBC.H:542
Definition AMReX_NonLocalBC.H:383
int J
Definition AMReX_NonLocalBC.H:385
int I
Definition AMReX_NonLocalBC.H:384
constexpr int operator()(int i) const noexcept
Definition AMReX_NonLocalBC.H:386
constexpr int operator()(int i) const noexcept
Definition AMReX_NonLocalBC.H:377
int I
Definition AMReX_NonLocalBC.H:376
int J
Definition AMReX_NonLocalBC.H:366
constexpr int operator()(int i) const noexcept
Definition AMReX_NonLocalBC.H:367
This is a permutation where only two components are swapped.
Definition AMReX_NonLocalBC.H:351
constexpr int operator()(int i) const noexcept
Swaps indices I and J.
Definition AMReX_NonLocalBC.H:357
Definition AMReX_BaseFab.H:78
int n
Definition AMReX_BaseFab.H:81
Definition AMReX_BaseFab.H:66
int i
Definition AMReX_BaseFab.H:69