1 /* ----------------------------------------------------------------------
2    SPARTA - Stochastic PArallel Rarefied-gas Time-accurate Analyzer
3    http://sparta.sandia.gov
4    Steve Plimpton, sjplimp@sandia.gov, Michael Gallis, magalli@sandia.gov
5    Sandia National Laboratories
6 
7    Copyright (2014) Sandia Corporation.  Under the terms of Contract
8    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
9    certain rights in this software.  This software is distributed under
10    the GNU General Public License.
11 
12    See the README file in the top-level SPARTA directory.
13 ------------------------------------------------------------------------- */
14 
15 #include "mpi.h"
16 #include "stdlib.h"
17 #include "error.h"
18 #include "universe.h"
19 #include "output.h"
20 #include "memory.h"
21 #include "accelerator_kokkos.h"
22 
23 using namespace SPARTA_NS;
24 
25 /* ---------------------------------------------------------------------- */
26 
Error(SPARTA * sparta)27 Error::Error(SPARTA *sparta) : Pointers(sparta) {}
28 
29 /* ----------------------------------------------------------------------
30    called by all procs in universe
31    close all output, screen, and log files in world and universe
32 ------------------------------------------------------------------------- */
33 
universe_all(const char * file,int line,const char * str)34 void Error::universe_all(const char *file, int line, const char *str)
35 {
36   MPI_Barrier(universe->uworld);
37 
38   if (universe->me == 0) {
39     if (universe->uscreen) fprintf(universe->uscreen,
40 				   "ERROR: %s (%s:%d)\n",str,file,line);
41     if (universe->ulogfile) fprintf(universe->ulogfile,
42 				    "ERROR: %s (%s:%d)\n",str,file,line);
43   }
44 
45   if (output) delete output;
46   if (universe->nworlds > 1) {
47     if (screen && screen != stdout) fclose(screen);
48     if (logfile) fclose(logfile);
49   }
50   if (universe->ulogfile) fclose(universe->ulogfile);
51 
52   if (sparta->kokkos) Kokkos::finalize();
53   MPI_Finalize();
54   exit(1);
55 }
56 
57 /* ----------------------------------------------------------------------
58    called by one proc in universe
59 ------------------------------------------------------------------------- */
60 
universe_one(const char * file,int line,const char * str)61 void Error::universe_one(const char *file, int line, const char *str)
62 {
63   if (universe->uscreen) {
64     fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n",
65 	    universe->me,str,file,line);
66     fflush(universe->uscreen);
67   }
68   MPI_Abort(universe->uworld,1);
69 }
70 
71 /* ----------------------------------------------------------------------
72    called by all procs in one world
73    close all output, screen, and log files in world
74 ------------------------------------------------------------------------- */
75 
all(const char * file,int line,const char * str)76 void Error::all(const char *file, int line, const char *str)
77 {
78   MPI_Barrier(world);
79 
80   int me;
81   MPI_Comm_rank(world,&me);
82 
83   if (me == 0) {
84     if (screen) fprintf(screen,"ERROR: %s (%s:%d)\n",str,file,line);
85     if (logfile) fprintf(logfile,"ERROR: %s (%s:%d)\n",str,file,line);
86   }
87 
88   if (output) delete output;
89   if (screen && screen != stdout) fclose(screen);
90   if (logfile) fclose(logfile);
91 
92   if (sparta->kokkos) Kokkos::finalize();
93   MPI_Finalize();
94   exit(1);
95 }
96 
97 /* ----------------------------------------------------------------------
98    called by one proc in world
99    write to world screen only if non-NULL on this proc
100    always write to universe screen
101 ------------------------------------------------------------------------- */
102 
one(const char * file,int line,const char * str)103 void Error::one(const char *file, int line, const char *str)
104 {
105   int me;
106   MPI_Comm_rank(world,&me);
107   if (screen) {
108     fprintf(screen,"ERROR on proc %d: %s (%s:%d)\n",
109             me,str,file,line);
110     fflush(screen);
111   }
112   if (universe->nworlds > 1) {
113     fprintf(universe->uscreen,"ERROR on proc %d: %s (%s:%d)\n",
114 	    universe->me,str,file,line);
115     fflush(universe->uscreen);
116   }
117   MPI_Abort(world,1);
118 }
119 
120 /* ----------------------------------------------------------------------
121    called by one proc in world
122    only write to screen if non-NULL on this proc since could be file
123 ------------------------------------------------------------------------- */
124 
warning(const char * file,int line,const char * str,int logflag)125 void Error::warning(const char *file, int line, const char *str, int logflag)
126 {
127   if (screen) fprintf(screen,"WARNING: %s (%s:%d)\n",str,file,line);
128   if (logflag && logfile) fprintf(logfile,"WARNING: %s (%s:%d)\n",
129 				  str,file,line);
130 }
131 
132 /* ----------------------------------------------------------------------
133    called by one proc in world, typically proc 0
134    write message to screen and logfile (if logflag is set)
135 ------------------------------------------------------------------------- */
136 
message(const char * file,int line,const char * str,int logflag)137 void Error::message(const char *file, int line, const char *str, int logflag)
138 {
139   if (screen) fprintf(screen,"%s (%s:%d)\n",str,file,line);
140   if (logflag && logfile) fprintf(logfile,"%s (%s:%d)\n",str,file,line);
141 }
142 
143 /* ----------------------------------------------------------------------
144    called by all procs in one world
145    close all output, screen, and log files in world
146 ------------------------------------------------------------------------- */
147 
done()148 void Error::done()
149 {
150   MPI_Barrier(world);
151 
152   if (output) delete output;
153   if (screen && screen != stdout) fclose(screen);
154   if (logfile) fclose(logfile);
155 
156   if (sparta->kokkos) Kokkos::finalize();
157   MPI_Finalize();
158   exit(1);
159 }
160