Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/v0.1.0/v0.9.0/cpp
DOLFINx  0.1.0
DOLFINx C++ interface
utils.h
1 // Copyright (C) 2009-2010 Anders Logg
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 <boost/functional/hash.hpp>
10 #include <cstring>
11 #include <dolfinx/common/MPI.h>
12 #include <limits>
13 #include <mpi.h>
14 #include <sstream>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 namespace dolfinx::common
20 {
21 
28 template <typename U, typename V>
29 std::pair<U, V> sort_unique(const U& indices, const V& values)
30 {
31  if (indices.size() != values.size())
32  throw std::runtime_error("Cannot sort two arrays of different lengths");
33 
34  std::vector<std::pair<typename U::value_type, typename V::value_type>> data(
35  indices.size());
36  for (std::size_t i = 0; i < indices.size(); ++i)
37  data[i] = {indices[i], values[i]};
38 
39  // Sort make unique
40  std::sort(data.begin(), data.end());
41  auto it = std::unique(data.begin(), data.end(),
42  [](auto& a, auto& b) { return a.first == b.first; });
43 
44  U indices_new;
45  V values_new;
46  indices_new.reserve(data.size());
47  values_new.reserve(data.size());
48  for (auto d = data.begin(); d != it; ++d)
49  {
50  indices_new.push_back(d->first);
51  values_new.push_back(d->second);
52  }
53 
54  return {std::move(indices_new), std::move(values_new)};
55 }
56 
58 std::string indent(std::string block);
59 
61 template <typename T>
62 std::string container_to_string(const T& x, const int precision,
63  const int linebreak)
64 {
65  std::stringstream s;
66  s.precision(precision);
67 
68  for (std::size_t i = 0; i < (std::size_t)x.size(); ++i)
69  {
70  if ((i + 1) % linebreak == 0 && linebreak != 0)
71  s << x.data()[i] << std::endl;
72  else
73  s << x.data()[i] << " ";
74  }
75  return s.str();
76 }
77 
79 template <class T>
80 std::size_t hash_local(const T& x)
81 {
82  boost::hash<T> hash;
83  return hash(x);
84 }
85 
89 template <class T>
90 std::int64_t hash_global(const MPI_Comm comm, const T& x)
91 {
92  // Compute local hash
93  int64_t local_hash = hash_local(x);
94 
95  // Gather hash keys on root process
96  std::vector<int64_t> all_hashes(dolfinx::MPI::size(comm));
97  MPI_Gather(&local_hash, 1, MPI_INT64_T, all_hashes.data(), 1, MPI_INT64_T, 0,
98  comm);
99 
100  // Hash the received hash keys
101  boost::hash<std::vector<int64_t>> hash;
102  int64_t global_hash = hash(all_hashes);
103 
104  // Broadcast hash key to all processes
105  MPI_Bcast(&global_hash, 1, MPI_INT64_T, 0, comm);
106 
107  return global_hash;
108 }
109 } // namespace dolfinx::common
dolfinx::common::hash_global
std::int64_t hash_global(const MPI_Comm comm, const T &x)
Return a hash for a distributed (MPI) object. A hash is computed on each process, and the hash of the...
Definition: utils.h:90
dolfinx::common::container_to_string
std::string container_to_string(const T &x, const int precision, const int linebreak)
Convert a container to string.
Definition: utils.h:62
dolfinx::common::hash_local
std::size_t hash_local(const T &x)
Return a hash of a given object.
Definition: utils.h:80
dolfinx::common::sort_unique
std::pair< U, V > sort_unique(const U &indices, const V &values)
Sort two arrays based on the values in array indices. Any duplicate indices and the corresponding val...
Definition: utils.h:29
dolfinx::MPI::size
static int size(MPI_Comm comm)
Return size of the group (number of processes) associated with the communicator.
Definition: MPI.cpp:85
dolfinx::common
Miscellaneous classes, functions and types.
dolfinx::common::indent
std::string indent(std::string block)
Indent string block.
Definition: utils.cpp:11