HΦ  3.2.0
wrapperMPI.c
Go to the documentation of this file.
1 /*
2 HPhi - Quantum Lattice Model Simulator
3 Copyright (C) 2015 The University of Tokyo
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
21 #ifdef MPI
22 #include <mpi.h>
23 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "wrapperMPI.h"
28 #ifdef _OPENMP
29 #include <omp.h>
30 #endif
31 #include <math.h>
32 #include <complex.h>
33 #include "splash.h"
34 #include "global.h"
35 
43 void InitializeMPI(int argc, char *argv[]){
44  int ierr;
45 
46 #ifdef MPI
47  ierr = MPI_Init(&argc, &argv);
48  ierr = MPI_Comm_size(MPI_COMM_WORLD, &nproc);
49  ierr = MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
50  if(ierr != 0) exitMPI(ierr);
51 #else
52  nproc = 1;
53  myrank = 0;
54 #endif
55  if (myrank == 0) stdoutMPI = stdout;
56  else stdoutMPI = fopen("/dev/null", "w");
57  splash();
58 
59 #pragma omp parallel default(none) shared(nthreads)
60 #pragma omp master
61 #ifdef _OPENMP
62  nthreads = omp_get_num_threads();
63 #else
64  nthreads=1;
65 #endif
66  fprintf(stdoutMPI, "\n\n##### Parallelization Info. #####\n\n");
67  fprintf(stdoutMPI, " OpenMP threads : %d\n", nthreads);
68  fprintf(stdoutMPI, " MPI PEs : %d \n\n", nproc);
69 }/*void InitializeMPI(int argc, char *argv[])*/
74 void FinalizeMPI(){
75  int ierr;
76 #ifdef MPI
77  ierr = MPI_Finalize();
78  if (ierr != 0) fprintf(stderr, "\n MPI_Finalize() = %d\n\n", ierr);
79 #endif
80  if (myrank != 0) fclose(stdoutMPI);
81 }
86 void exitMPI(
87  int errorcode
88 )
89 {
90  int ierr;
91  fflush(stdout);
92 #ifdef MPI
93  fprintf(stdout,"\n\n ####### [HPhi] You DO NOT have to WORRY about the following MPI-ERROR MESSAGE. #######\n\n");
94  ierr = MPI_Abort(MPI_COMM_WORLD, errorcode);
95  ierr = MPI_Finalize();
96  if (ierr != 0) fprintf(stderr, "\n MPI_Finalize() = %d\n\n", ierr);
97 #endif
98  exit(errorcode);
99 }/*void exitMPI*/
105 FILE* fopenMPI(
106  const char* FileName,
107  const char* mode
108 ){
109  FILE* fp;
110 
111  if (myrank == 0) fp = fopen(FileName, mode);
112  else fp = fopen("/dev/null", "w");
113 
114  return fp;
115 }/*FILE* fopenMPI*/
122 char* fgetsMPI(
123  char* InputString,
124  int maxcount,
125  FILE* fp
126 ){
127  int inull;
128  char *ctmp;
129 
130  ctmp = InputString;
131  inull = 0;
132  if (myrank == 0) {
133  ctmp = fgets(InputString, maxcount, fp);
134  if (ctmp == NULL){
135  inull = 1;
136  }
137 
138  while(*InputString == '\n' || strncmp(InputString, "#", 1)==0){
139  ctmp = fgets(InputString, maxcount, fp);
140  if (ctmp == NULL){
141  inull=1;
142  break;
143  }
144  }
145  }
146 #ifdef MPI
147  MPI_Bcast(InputString, maxcount, MPI_CHAR, 0, MPI_COMM_WORLD);
148  MPI_Bcast(&inull, 1, MPI_INT, 0, MPI_COMM_WORLD);
149 #endif
150  if (myrank != 0 && inull == 1) {
151  ctmp = NULL;
152  }
153 
154  return ctmp;
155 }/*char* fgetsMPI*/
160 void BarrierMPI(){
161 #ifdef MPI
162  MPI_Barrier(MPI_COMM_WORLD);
163 #endif
164 }/*void BarrierMPI()*/
171 unsigned long int MaxMPI_li(
172  unsigned long int idim
173 ){
174 #ifdef MPI
175  int ierr;
176  ierr = MPI_Allreduce(MPI_IN_PLACE, &idim, 1,
177  MPI_UNSIGNED_LONG, MPI_MAX, MPI_COMM_WORLD);
178  if(ierr != 0) exitMPI(-1);
179 #endif
180  return(idim);
181 }/*unsigned long int MaxMPI_li*/
188 double MaxMPI_d(
189  double dvalue
190 ){
191 #ifdef MPI
192  int ierr;
193  ierr = MPI_Allreduce(MPI_IN_PLACE, &dvalue, 1,
194  MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
195  if(ierr != 0) exitMPI(-1);
196 #endif
197  return(dvalue);
198 }/*double MaxMPI_d*/
205 double complex SumMPI_dc(
206  double complex norm
207 ){
208 #ifdef MPI
209  int ierr;
210  ierr = MPI_Allreduce(MPI_IN_PLACE, &norm, 1,
211  MPI_DOUBLE_COMPLEX, MPI_SUM, MPI_COMM_WORLD);
212  if(ierr != 0) exitMPI(-1);
213 #endif
214  return(norm);
215 }/*double complex SumMPI_dc*/
222 double SumMPI_d(
223  double norm
224 ){
225 #ifdef MPI
226  int ierr;
227  ierr = MPI_Allreduce(MPI_IN_PLACE, &norm, 1,
228  MPI_DOUBLE_PRECISION, MPI_SUM, MPI_COMM_WORLD);
229  if(ierr != 0) exitMPI(-1);
230 #endif
231  return(norm);
232 }/*double SumMPI_d*/
239 unsigned long int SumMPI_li(
240  unsigned long int idim
241 ){
242 #ifdef MPI
243  int ierr;
244  ierr = MPI_Allreduce(MPI_IN_PLACE, &idim, 1,
245  MPI_UNSIGNED_LONG, MPI_SUM, MPI_COMM_WORLD);
246  if(ierr != 0) exitMPI(-1);
247 #endif
248  return(idim);
249 }/*unsigned long int SumMPI_li*/
257  int idim
258 ) {
259 #ifdef MPI
260  int ierr;
261  ierr = MPI_Allreduce(MPI_IN_PLACE, &idim, 1,
262  MPI_INT, MPI_SUM, MPI_COMM_WORLD);
263  if(ierr != 0) exitMPI(-1);
264 #endif
265  return(idim);
266 }/*int SumMPI_i*/
273 unsigned long int BcastMPI_li(
274  int root,
275  unsigned long int idim
276 ) {
277  unsigned long int idim0;
278  idim0 = idim;
279 #ifdef MPI
280  MPI_Bcast(&idim0, 1, MPI_UNSIGNED_LONG, root, MPI_COMM_WORLD);
281 #endif
282  return(idim0);
283 }/*unsigned long int BcastMPI_li*/
289 double NormMPI_dc(
290  unsigned long int idim,
291  double complex *_v1
292 ){
293  double complex cdnorm=0;
294  double dnorm =0;
295  unsigned long int i;
296  //DEBUG
297 #pragma omp parallel for default(none) private(i) firstprivate(myrank) shared(_v1, idim) reduction(+: cdnorm)
298  for(i=1;i<=idim;i++){
299  cdnorm += conj(_v1[i])*_v1[i];
300  }
301 #ifdef MPI
302  cdnorm = SumMPI_dc(cdnorm);
303 #endif
304  dnorm=creal(cdnorm);
305  dnorm=sqrt(dnorm);
306 
307  return dnorm;
308 }/*double NormMPI_dc*/
314 double complex VecProdMPI(
315  long unsigned int ndim,
316  double complex *v1,
317  double complex *v2
318 ){
319  long unsigned int idim;
320  double complex prod;
321 
322  prod = 0.0;
323 #pragma omp parallel for default(none) shared(v1,v2,ndim) private(idim) reduction(+: prod)
324  for (idim = 1; idim <= ndim; idim++) prod += conj(v1[idim]) * v2[idim];
325  prod = SumMPI_dc(prod);
326 
327  return(prod);
328 }/*double complex VecProdMPI*/
void exitMPI(int errorcode)
MPI Abortation wrapper.
Definition: wrapperMPI.c:86
double complex SumMPI_dc(double complex norm)
MPI wrapper function to obtain sum of Double complex across processes.
Definition: wrapperMPI.c:205
unsigned long int BcastMPI_li(int root, unsigned long int idim)
MPI wrapper function to broadcast unsigned long integer across processes.
Definition: wrapperMPI.c:273
double complex * v1
Definition: global.h:35
double complex * v2
Definition: global.h:36
double SumMPI_d(double norm)
MPI wrapper function to obtain sum of Double across processes.
Definition: wrapperMPI.c:222
double MaxMPI_d(double dvalue)
MPI wrapper function to obtain maximum Double across processes.
Definition: wrapperMPI.c:188
int nthreads
Number of Threads, defined in InitializeMPI()
Definition: global.h:164
double NormMPI_dc(unsigned long int idim, double complex *_v1)
Compute norm of process-distributed vector .
Definition: wrapperMPI.c:289
void BarrierMPI()
MPI barrier wrapper.
Definition: wrapperMPI.c:160
void splash()
Print logo mark and version number.
Definition: splash.c:25
int nproc
Number of processors, defined in InitializeMPI()
Definition: global.h:162
int SumMPI_i(int idim)
MPI wrapper function to obtain sum of integer across processes.
Definition: wrapperMPI.c:256
unsigned long int MaxMPI_li(unsigned long int idim)
MPI wrapper function to obtain maximum unsigned long integer across processes.
Definition: wrapperMPI.c:171
void FinalizeMPI()
MPI Finitialization wrapper.
Definition: wrapperMPI.c:74
double complex VecProdMPI(long unsigned int ndim, double complex *v1, double complex *v2)
Compute conjugate scaler product of process-distributed vector .
Definition: wrapperMPI.c:314
int myrank
Process ID, defined in InitializeMPI()
Definition: global.h:163
char * fgetsMPI(char *InputString, int maxcount, FILE *fp)
MPI file I/O (get a line, fgets) wrapper. Only the root node (myrank = 0) reads and broadcast string...
Definition: wrapperMPI.c:122
unsigned long int SumMPI_li(unsigned long int idim)
MPI wrapper function to obtain sum of unsigned long integer across processes.
Definition: wrapperMPI.c:239
FILE * fopenMPI(const char *FileName, const char *mode)
MPI file I/O (open) wrapper. Only the root node (myrank = 0) should be open/read/write (small) parame...
Definition: wrapperMPI.c:105
void InitializeMPI(int argc, char *argv[])
MPI initialization wrapper Process ID (myrank), Number of processes (nproc), Number of threads (nthre...
Definition: wrapperMPI.c:43
FILE * stdoutMPI
File pointer to the standard output defined in InitializeMPI()
Definition: global.h:165