diff --git a/libsrc/core/taskmanager.hpp b/libsrc/core/taskmanager.hpp index af2ae0c7..c8373627 100644 --- a/libsrc/core/taskmanager.hpp +++ b/libsrc/core/taskmanager.hpp @@ -1016,6 +1016,67 @@ public: #endif // USE_NUMA + // Helper function to calculate coloring of a set of indices for parallel processing of independent elements/points/etc. + // Assigns a color to each of colors.Size() elements, such that two elements with the same color don't share a common 'dof', + // the mapping from element to dofs is provided by the function getDofs(int) -> iterable + // + // Returns the number of used colors + template + int ComputeColoring( FlatArray colors, size_t ndofs, Tmask const & getDofs) + { + static_assert(sizeof(unsigned int)==4, "Adapt type of mask array"); + auto n = colors.Size(); + + Array mask(ndofs); + + int colored_blocks = 0; + + // We are coloring with 32 colors at once and use each bit to mask conflicts + unsigned int check = 0; + unsigned int checkbit = 0; + + int current_color = 0; + colors = -1; + int maxcolor = 0; + + while(colored_blocks-1) continue; + check = 0; + const auto & dofs = getDofs(i); + + // Check if adjacent dofs are already marked by current color + for (auto dof : dofs) + check|=mask[dof]; + + // Did we find a free color? + if(check != 0xFFFFFFFF) + { + checkbit = 1; + int color = current_color; + // find the actual color, which is free (out of 32) + while (check & checkbit) + { + color++; + checkbit *= 2; + } + colors[i] = color; + maxcolor = color > maxcolor ? color : maxcolor; + colored_blocks++; + // mask all adjacent dofs with the found color + for (auto dof : dofs) + mask[dof] |= checkbit; + } + } + current_color+=32; + } + return maxcolor+1; + } + + }