DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
utils.h
1// Copyright (C) 2009-2025 Anders Logg and Garth N. Wells
2//
3// This file is part of DOLFINx (https://www.fenicsproject.org)
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6
7#pragma once
8
9#include "MPI.h"
10#include <algorithm>
11#include <boost/functional/hash.hpp>
12#include <cstddef>
13#include <cstdint>
14#include <dolfinx/graph/AdjacencyList.h>
15#include <iterator>
16#include <mpi.h>
17#include <ranges>
18#include <stdexcept>
19#include <string>
20#include <tuple>
21#include <utility>
22#include <vector>
23
25namespace dolfinx::common
26{
36template <std::ranges::input_range U, std::ranges::input_range V>
37std::pair<std::vector<typename U::value_type>,
38 std::vector<typename V::value_type>>
39sort_unique(const U& indices, const V& values)
40{
41 if (indices.size() != values.size())
42 throw std::runtime_error("Cannot sort two arrays of different lengths");
43
44 using T = std::pair<typename U::value_type, typename V::value_type>;
45 std::vector<T> data(indices.size());
46 std::ranges::transform(indices, values, data.begin(),
47 [](const auto& idx, const auto& v) -> T
48 { return {idx, v}; });
49
50 // Sort by (index, value), then drop duplicate indices keeping the
51 // first of each run, i.e. the smallest value (as documented).
52 std::ranges::sort(data);
53 auto it = std::ranges::unique(data, [](const auto& a, const auto& b)
54 { return a.first == b.first; })
55 .begin();
56
57 std::vector<typename U::value_type> indices_new;
58 std::vector<typename V::value_type> values_new;
59 std::size_t n = std::distance(data.begin(), it);
60 indices_new.reserve(n);
61 values_new.reserve(n);
62 std::transform(data.begin(), it, std::back_inserter(indices_new),
63 [](const auto& d) { return d.first; });
64 std::transform(data.begin(), it, std::back_inserter(values_new),
65 [](const auto& d) { return d.second; });
66
67 return {std::move(indices_new), std::move(values_new)};
68}
69
77template <class T>
78std::size_t hash_local(const T& x)
79{
80 boost::hash<T> hash;
81 return hash(x);
82}
83
95template <class T>
96std::size_t hash_global(MPI_Comm comm, const T& x)
97{
98 // Compute local hash
99 std::size_t local_hash = hash_local(x);
100
101 // Gather hash keys on root process
102 std::vector<std::size_t> all_hashes(dolfinx::MPI::size(comm));
103 int err = MPI_Gather(&local_hash, 1, dolfinx::MPI::mpi_t<std::size_t>,
104 all_hashes.data(), 1, dolfinx::MPI::mpi_t<std::size_t>,
105 0, comm);
106 dolfinx::MPI::check_error(comm, err);
107
108 // Hash the received hash keys
109 boost::hash<std::vector<std::size_t>> hash;
110 std::size_t global_hash = hash(all_hashes);
111
112 // Broadcast hash key to all processes
113 err = MPI_Bcast(&global_hash, 1, dolfinx::MPI::mpi_t<std::size_t>, 0, comm);
114 dolfinx::MPI::check_error(comm, err);
115
116 return global_hash;
117}
118
132std::string comm_to_json(
133 const graph::AdjacencyList<std::tuple<int, std::size_t, std::int8_t>,
134 std::pair<std::int32_t, std::int32_t>>& g);
135} // namespace dolfinx::common
This class provides a static adjacency list data structure.
Definition AdjacencyList.h:41
MPI_Datatype mpi_t
Retrieves the MPI data type associated to the provided type.
Definition MPI.h:257
void check_error(MPI_Comm comm, int code)
Check MPI error code. If the error code is not equal to MPI_SUCCESS, then std::abort is called.
Definition MPI.cpp:80
int size(MPI_Comm comm)
Definition MPI.cpp:72
Miscellaneous classes, functions and types.
Definition dolfinx_common.h:8
std::pair< std::vector< typename U::value_type >, std::vector< typename V::value_type > > sort_unique(const U &indices, const V &values)
Sort two arrays based on the values in array indices.
Definition utils.h:39
std::size_t hash_global(MPI_Comm comm, const T &x)
Compute a hash for a distributed (MPI) object.
Definition utils.h:96
std::size_t hash_local(const T &x)
Compute a hash of a given object.
Definition utils.h:78
std::string comm_to_json(const graph::AdjacencyList< std::tuple< int, std::size_t, std::int8_t >, std::pair< std::int32_t, std::int32_t > > &g)
Build communication graph data as a JSON string.