]> https://gitweb.dealii.org/ - dealii.git/commitdiff
NoncontiguousPartitioner: allow duplicate ghost indices 18332/head
authorPeter Munch <peterrmuench@gmail.com>
Sat, 5 Apr 2025 20:32:05 +0000 (22:32 +0200)
committerPeter Munch <peterrmuench@gmail.com>
Sat, 5 Apr 2025 20:32:05 +0000 (22:32 +0200)
include/deal.II/base/mpi_noncontiguous_partitioner.h
include/deal.II/base/mpi_noncontiguous_partitioner.templates.h
source/base/mpi_noncontiguous_partitioner.cc
tests/base/mpi_noncontiguous_partitioner_03.cc
tests/base/mpi_noncontiguous_partitioner_03.mpirun=2.output

index 0072d787c0ddc29ef6e926960d024776e17e0dfb..b721166c1d3e44033b630191f1c52d62079280eb 100644 (file)
@@ -320,10 +320,29 @@ namespace Utilities
        * Local index of each entry in recv_buffer within the destination
        * vector.
        *
+       * In the case that an entry is more than once requested by the
+       * same rank, local index of each entry in recv_buffer within
+       * recv_indices_duplicates_ptr.
+       *
        * @note Together with `recv_ptr` this forms a CRS data structure.
        */
       std::vector<types::global_dof_index> recv_indices;
 
+      /**
+       * In the case that an entry is more than once requested by the
+       * same rank, offset of each index in recv_indices_duplicates.
+       */
+      std::vector<unsigned int> recv_indices_duplicates_ptr;
+
+      /**
+       * Local index of each entry within the destination vector in the
+       * case that an entry is more than once requested by the same rank.
+       *
+       * @note Together with `recv_indices_duplicates_ptr`
+       * this forms a CRS data structure.
+       */
+      std::vector<unsigned int> recv_indices_duplicates;
+
       /**
        * Buffer containing the values sorted by rank for sending and receiving.
        *
index 3d5bd9402759a6d425f40b618970a078baf45712..cfc0dd0416a7347a7a453e3abf22402f77f43dce 100644 (file)
@@ -206,12 +206,21 @@ namespace Utilities
           AssertThrowMPI(ierr);
 
           AssertIndexRange(i + 1, recv_ptr.size());
-          for (types::global_dof_index j = recv_ptr[i], c = 0;
-               j < recv_ptr[i + 1];
-               ++j, ++c)
+          for (types::global_dof_index j = recv_ptr[i]; j < recv_ptr[i + 1];
+               ++j)
             for (unsigned int comp = 0; comp < n_components_to_be_used; ++comp)
-              dst[recv_indices[j] * n_components_to_be_used + comp] =
-                buffers[(recv_ptr[i] + c) * n_components_to_be_used + comp];
+              {
+                const auto &value = buffers[j * n_components_to_be_used + comp];
+
+                if (recv_indices_duplicates_ptr.empty())
+                  dst[recv_indices[j] * n_components_to_be_used + comp] = value;
+                else
+                  for (auto k = recv_indices_duplicates_ptr[recv_indices[j]];
+                       k < recv_indices_duplicates_ptr[recv_indices[j] + 1];
+                       ++k)
+                    dst[recv_indices_duplicates[k] * n_components_to_be_used +
+                        comp] = value;
+              }
         }
 
       // wait that all data packages have been sent
index 9effc1f79f39064750cc5b9e409414d7fcd633ed..8eb8da23cdd24cf53f8c5e2f5eee2e0f228a7481 100644 (file)
@@ -216,15 +216,37 @@ namespace Utilities
       }
 
       {
-        std::vector<types::global_dof_index> temp_map_recv(
+        std::vector<std::vector<types::global_dof_index>> temp_map_recv(
           index_set_want.n_elements());
 
         for (types::global_dof_index i = 0; i < indices_want.size(); ++i)
           if (indices_want[i] != numbers::invalid_dof_index)
-            temp_map_recv[index_set_want.index_within_set(indices_want[i])] = i;
+            temp_map_recv[index_set_want.index_within_set(indices_want[i])]
+              .push_back(i);
 
-        for (auto &i : recv_indices)
-          i = temp_map_recv[i];
+        const bool use_fast_path =
+          std::all_of(temp_map_recv.begin(),
+                      temp_map_recv.end(),
+                      [&](const auto &x) { return x.size() == 1; });
+
+        if (use_fast_path)
+          {
+            for (auto &i : recv_indices)
+              i = temp_map_recv[i][0];
+          }
+        else
+          {
+            recv_indices_duplicates_ptr = {0};
+
+            for (const auto &indices : temp_map_recv)
+              {
+                for (const auto &index : indices)
+                  recv_indices_duplicates.emplace_back(index);
+
+                recv_indices_duplicates_ptr.push_back(
+                  recv_indices_duplicates.size());
+              }
+          }
       }
     }
   } // namespace MPI
index c93783b666d21143c5905c3e3074d0bbdf936845..e8b758a421cb588e47ffbaf875cac353a186863b 100644 (file)
@@ -87,4 +87,14 @@ main(int argc, char *argv[])
       test(comm, {4, 5, 6, 7}, {0, 1, 2, 3});
     deallog.pop();
   }
+
+  {
+    deallog.push("duplicates");
+
+    if (rank == 0)
+      test(comm, {0, 1, 2, 3}, {4, 4, 5, 6, 7, 6});
+    else
+      test(comm, {4, 5, 6, 7}, {0, 1, 2, 1, 1, 3});
+    deallog.pop();
+  }
 }
index bfef1b6851707952a0ce59978d6596c8bac9022b..5b76439aa6eea336b93a8962180f01b2c6d8ade1 100644 (file)
@@ -5,6 +5,8 @@ DEAL:0:padding-src::0 1 2 3 4
 DEAL:0:padding-src::100 101 102 103 
 DEAL:0:padding-dst::0 1 2 3 
 DEAL:0:padding-dst::100 101 0 102 103 
+DEAL:0:duplicates::0 1 2 3 
+DEAL:0:duplicates::100 100 101 102 103 102 
 
 DEAL:1:padding-non::100 101 102 103 
 DEAL:1:padding-non::0 1 2 3 
@@ -12,4 +14,6 @@ DEAL:1:padding-src::100 101 102 103
 DEAL:1:padding-src::0 1 3 4 
 DEAL:1:padding-dst::100 101 102 103 
 DEAL:1:padding-dst::0 1 2 3 
+DEAL:1:duplicates::100 101 102 103 
+DEAL:1:duplicates::0 1 2 1 1 3 
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.