DOLFINx
0.12.0.0
DOLFINx C++
Toggle main menu visibility
Loading...
Searching...
No Matches
dolfinx
common
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 <iterator>
15
#include <mpi.h>
16
#include <ranges>
17
#include <stdexcept>
18
#include <tuple>
19
#include <utility>
20
#include <vector>
21
23
namespace
dolfinx::common
24
{
34
template
<std::ranges::input_range U, std::ranges::input_range V>
35
std::pair<std::vector<typename U::value_type>,
36
std::vector<typename V::value_type>>
37
sort_unique
(
const
U& indices,
const
V& values)
38
{
39
if
(indices.size() != values.size())
40
throw
std::runtime_error(
"Cannot sort two arrays of different lengths"
);
41
42
using
T = std::pair<typename U::value_type, typename V::value_type>;
43
std::vector<T> data(indices.size());
44
std::ranges::transform(indices, values, data.begin(),
45
[](
const
auto
& idx,
const
auto
& v) -> T
46
{ return {idx, v}; });
47
48
// Sort by (index, value), then drop duplicate indices keeping the
49
// first of each run, i.e. the smallest value (as documented).
50
std::ranges::sort(data);
51
auto
it = std::ranges::unique(data, [](
const
auto
& a,
const
auto
& b)
52
{
return
a.first == b.first; })
53
.begin();
54
55
std::vector<typename U::value_type> indices_new;
56
std::vector<typename V::value_type> values_new;
57
std::size_t n = std::ranges::distance(data.begin(), it);
58
indices_new.reserve(n);
59
values_new.reserve(n);
60
std::transform(data.begin(), it, std::back_inserter(indices_new),
61
[](
const
auto
& d) { return d.first; });
62
std::transform(data.begin(), it, std::back_inserter(values_new),
63
[](
const
auto
& d) { return d.second; });
64
65
return
{std::move(indices_new), std::move(values_new)};
66
}
67
75
template
<
class
T>
76
std::size_t
hash_local
(
const
T& x)
77
{
78
boost::hash<T> hash;
79
return
hash(x);
80
}
81
93
template
<
class
T>
94
std::size_t
hash_global
(MPI_Comm comm,
const
T& x)
95
{
96
// Compute local hash
97
std::size_t local_hash =
hash_local
(x);
98
99
// Gather hash keys on root process
100
std::vector<std::size_t> all_hashes(
dolfinx::MPI::size
(comm));
101
int
err = MPI_Gather(&local_hash, 1,
dolfinx::MPI::mpi_t<std::size_t>
,
102
all_hashes.data(), 1,
dolfinx::MPI::mpi_t<std::size_t>
,
103
0, comm);
104
dolfinx::MPI::check_error
(comm, err);
105
106
// Hash the received hash keys
107
boost::hash<std::vector<std::size_t>> hash;
108
std::size_t global_hash = hash(all_hashes);
109
110
// Broadcast hash key to all processes
111
err = MPI_Bcast(&global_hash, 1,
dolfinx::MPI::mpi_t<std::size_t>
, 0, comm);
112
dolfinx::MPI::check_error
(comm, err);
113
114
return
global_hash;
115
}
116
117
}
// namespace dolfinx::common
dolfinx::MPI::mpi_t
MPI_Datatype mpi_t
Retrieves the MPI data type associated to the provided type.
Definition
MPI.h:320
dolfinx::MPI::check_error
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:89
dolfinx::MPI::size
int size(MPI_Comm comm)
Definition
MPI.cpp:81
dolfinx::common
Miscellaneous classes, functions and types.
Definition
dolfinx_common.h:8
dolfinx::common::sort_unique
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:37
dolfinx::common::hash_global
std::size_t hash_global(MPI_Comm comm, const T &x)
Compute a hash for a distributed (MPI) object.
Definition
utils.h:94
dolfinx::common::hash_local
std::size_t hash_local(const T &x)
Compute a hash of a given object.
Definition
utils.h:76
Generated by
1.17.0