pism_utilities.hh (3795B)
1 /* Copyright (C) 2016, 2017, 2018, 2019 PISM Authors 2 * 3 * This file is part of PISM. 4 * 5 * PISM is free software; you can redistribute it and/or modify it under the 6 * terms of the GNU General Public License as published by the Free Software 7 * Foundation; either version 3 of the License, or (at your option) any later 8 * version. 9 * 10 * PISM is distributed in the hope that it will be useful, but WITHOUT ANY 11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 13 * details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with PISM; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 #ifndef _PISM_UTILITIES_H_ 21 #define _PISM_UTILITIES_H_ 22 23 #include <cstdint> // uint16_t, uint32_t 24 25 #include <algorithm> // std::min, std::max 26 #include <string> 27 #include <vector> 28 #include <set> 29 30 #include <mpi.h> 31 32 namespace pism { 33 34 // Utilities that do not expose PETSc's or PISM's API. 35 36 #ifndef __GNUC__ 37 # define __attribute__(x) /* nothing */ 38 #endif 39 40 double get_time(); 41 std::string timestamp(MPI_Comm com); 42 std::string username_prefix(MPI_Comm com); 43 std::string args_string(); 44 std::string filename_add_suffix(const std::string &filename, 45 const std::string &separator, 46 const std::string &suffix); 47 48 double wall_clock_hours(MPI_Comm com, double start_time); 49 50 51 // array 52 bool is_increasing(const std::vector<double> &a); 53 54 // string 55 bool ends_with(const std::string &str, const std::string &suffix); 56 57 std::string join(const std::vector<std::string> &strings, const std::string &separator); 58 59 std::vector<std::string> split(const std::string &input, char separator); 60 61 std::set<std::string> set_split(const std::string &input, char separator); 62 63 std::string set_join(const std::set<std::string> &input, const std::string& separator); 64 65 // set 66 bool member(const std::string &string, const std::set<std::string> &set); 67 68 /*! Helper template function for computing set unions. 69 * Ensures that elements of a take precedence. For example, if 70 * 71 * a = {{1, 2}, {3, 4}} 72 * b = {{1, 4}, {5, 6}} 73 * 74 * combine(a, b) will use the pair {1, 2} from a, not {1, 4} from b. 75 * 76 * This behavior relies on the fact that std::map::insert({a, b}) is a no-op if a key equivalent to 77 * a is already present. 78 * 79 * This is similar to a set union, but it is not symmetric. (I would expect set_union(a, b) to be 80 * the same as set_union(b, a)). 81 */ 82 template<typename T> 83 T combine(const T &a, const T&b) { 84 T result = a; 85 for (const auto &element : b) { 86 result.insert(element); 87 } 88 return result; 89 } 90 91 inline double clip(double x, double a, double b) { 92 return std::min(std::max(a, x), b); 93 } 94 95 double vector_min(const std::vector<double> &input); 96 97 double vector_max(const std::vector<double> &input); 98 99 // parallel 100 void GlobalReduce(MPI_Comm comm, double *local, double *result, int count, MPI_Op op); 101 102 void GlobalMin(MPI_Comm comm, double *local, double *result, int count); 103 104 void GlobalMax(MPI_Comm comm, double *local, double *result, int count); 105 106 void GlobalSum(MPI_Comm comm, double *local, double *result, int count); 107 108 double GlobalMin(MPI_Comm comm, double local); 109 110 double GlobalMax(MPI_Comm comm, double local); 111 112 double GlobalSum(MPI_Comm comm, double local); 113 114 unsigned int GlobalSum(MPI_Comm comm, unsigned int input); 115 116 int GlobalSum(MPI_Comm comm, int input); 117 118 std::string version(); 119 120 std::string printf(const char *format, ...) __attribute__((format(printf, 1, 2))); 121 122 void validate_format_string(const std::string &format); 123 124 uint64_t fletcher64(const uint32_t *data, size_t len); 125 126 } // end of namespace pism 127 128 129 #endif /* _PISM_UTILITIES_H_ */