Apply clang-format to source tree
[alexxy/gromacs.git] / src / gromacs / utility / basenetwork.cpp
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5  * Copyright (c) 2001-2004, The GROMACS development team.
6  * Copyright (c) 2013,2014,2015,2016,2017,2018,2019, by the GROMACS development team, led by
7  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8  * and including many others, as listed in the AUTHORS file in the
9  * top-level source directory and at http://www.gromacs.org.
10  *
11  * GROMACS is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public License
13  * as published by the Free Software Foundation; either version 2.1
14  * of the License, or (at your option) any later version.
15  *
16  * GROMACS is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with GROMACS; if not, see
23  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
25  *
26  * If you want to redistribute modifications to GROMACS, please
27  * consider that scientific software is very special. Version
28  * control is crucial - bugs must be traceable. We will be happy to
29  * consider code for inclusion in the official distribution, but
30  * derived work must not be called official GROMACS. Details are found
31  * in the README & COPYING files - if they are missing, get the
32  * official version at http://www.gromacs.org.
33  *
34  * To help us fund GROMACS development, we humbly ask that you cite
35  * the research papers on the package. Check out http://www.gromacs.org.
36  */
37 #include "gmxpre.h"
38
39 #include "basenetwork.h"
40
41 #include "config.h"
42
43 #include <climits>
44 #include <cstdio>
45 #include <cstdlib>
46 #include <cstring>
47
48 #include "gromacs/utility/cstringutil.h"
49 #include "gromacs/utility/fatalerror.h"
50 #include "gromacs/utility/gmxmpi.h"
51
52 bool gmx_mpi_initialized()
53 {
54 #if !GMX_MPI
55     return false;
56 #else
57     int n;
58     MPI_Initialized(&n);
59
60     return n != 0;
61 #endif
62 }
63
64 int gmx_node_num()
65 {
66 #if !GMX_MPI
67     return 1;
68 #else
69 #    if GMX_THREAD_MPI
70     if (!gmx_mpi_initialized())
71     {
72         return 1;
73     }
74 #    endif
75     int i;
76     (void)MPI_Comm_size(MPI_COMM_WORLD, &i);
77     return i;
78 #endif
79 }
80
81 int gmx_node_rank()
82 {
83 #if !GMX_MPI
84     return 0;
85 #else
86 #    if GMX_THREAD_MPI
87     if (!gmx_mpi_initialized())
88     {
89         return 0;
90     }
91 #    endif
92     int i;
93     (void)MPI_Comm_rank(MPI_COMM_WORLD, &i);
94     return i;
95 #endif
96 }
97
98 static int mpi_hostname_hash()
99 {
100     int hash_int;
101
102 #if GMX_LIB_MPI
103     int  resultlen;
104     char mpi_hostname[MPI_MAX_PROCESSOR_NAME];
105
106     /* This procedure can only differentiate nodes with different names.
107      * Architectures where different physical nodes have identical names,
108      * such as IBM Blue Gene, should use an architecture specific solution.
109      */
110     MPI_Get_processor_name(mpi_hostname, &resultlen);
111
112     /* The string hash function returns an unsigned int. We cast to an int.
113      * Negative numbers are converted to positive by setting the sign bit to 0.
114      * This makes the hash one bit smaller.
115      * A 63-bit hash (with 64-bit int) should be enough for unique node hashes,
116      * even on a million node machine. 31 bits might not be enough though!
117      */
118     hash_int = static_cast<int>(gmx_string_fullhash_func(mpi_hostname, gmx_string_hash_init));
119     if (hash_int < 0)
120     {
121         hash_int -= INT_MIN;
122     }
123 #else
124
125     /* thread-MPI currently puts the thread number in the process name,
126      * we might want to change this, as this is inconsistent with what
127      * most MPI implementations would do when running on a single node.
128      */
129     hash_int = 0;
130 #endif
131
132     return hash_int;
133 }
134
135 int gmx_physicalnode_id_hash()
136 {
137     int hash = 0;
138
139     if (GMX_MPI)
140     {
141         hash = mpi_hostname_hash();
142     }
143
144     if (debug)
145     {
146         fprintf(debug, "In gmx_physicalnode_id_hash: hash %d\n", hash);
147     }
148
149     return hash;
150 }
151
152 void gmx_broadcast_world(int size, void* buffer)
153 {
154 #if GMX_MPI
155     MPI_Bcast(buffer, size, MPI_BYTE, 0, MPI_COMM_WORLD);
156 #else
157     GMX_UNUSED_VALUE(size);
158     GMX_UNUSED_VALUE(buffer);
159 #endif
160 }
161
162 #if GMX_LIB_MPI
163 void gmx_abort(int errorno)
164 {
165     MPI_Abort(MPI_COMM_WORLD, errorno);
166     std::abort();
167 }
168 #endif