1 |
|
2 |
/******************************************************* |
3 |
* |
4 |
* Copyright (c) 2003-2009 by University of Queensland |
5 |
* Earth Systems Science Computational Center (ESSCC) |
6 |
* http://www.uq.edu.au/esscc |
7 |
* |
8 |
* Primary Business: Queensland, Australia |
9 |
* Licensed under the Open Software License version 3.0 |
10 |
* http://www.opensource.org/licenses/osl-3.0.php |
11 |
* |
12 |
*******************************************************/ |
13 |
|
14 |
|
15 |
#include <Python.h> |
16 |
#ifdef PASO_MPI |
17 |
#include <mpi.h> |
18 |
#endif |
19 |
#include <iostream> |
20 |
#include <stdexcept> |
21 |
|
22 |
extern "C"{ |
23 |
#include "paso/Paso_MPI.h" |
24 |
} |
25 |
#ifdef PASO_MPI |
26 |
|
27 |
int main( int argc, char **argv ) { |
28 |
int status = 0; |
29 |
int provided; |
30 |
Paso_MPIInfo *mpi_info=NULL; |
31 |
try |
32 |
{ |
33 |
/* |
34 |
* Initialise MPI |
35 |
*/ |
36 |
/* status = MPI_Init(&argc, &argv); */ |
37 |
status = MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided ); |
38 |
if (status != MPI_SUCCESS) { |
39 |
std::cerr << argv[0] << ": MPI_Init failed, exiting." << std::endl; |
40 |
return status; |
41 |
} |
42 |
mpi_info = Paso_MPIInfo_alloc( MPI_COMM_WORLD ); |
43 |
|
44 |
if( mpi_info->rank ) |
45 |
{ |
46 |
char fname[256]; |
47 |
sprintf( fname, "stdout_%04d.out", mpi_info->rank ); |
48 |
FILE *fp_out; |
49 |
fp_out = freopen( fname, "w+", stdout ); |
50 |
sprintf( fname, "stdout_%04d.err", mpi_info->rank ); |
51 |
FILE *fp_err; |
52 |
fp_err = freopen( fname, "w+", stderr ); |
53 |
} |
54 |
/* |
55 |
* Start the python parser |
56 |
*/ |
57 |
status = Py_Main(argc, argv); |
58 |
|
59 |
/* |
60 |
* Close down MPI. |
61 |
* status==1 : uncaught python exception |
62 |
* status==2 : invalid python cmd line |
63 |
* status>2 : supposed to be param of sys.exit() |
64 |
* sys.exit doesn't return as it should. |
65 |
* |
66 |
* I have made an exception for 2 because calling MPI_Abort |
67 |
* can display pretty ugly messages for not typing params |
68 |
* properly. |
69 |
* Yes that means you probably shouldn't use 2 as an exit code |
70 |
* but we don't really recommend sys.exit anyway. |
71 |
*/ |
72 |
if ((status!=0) && (status!=2)) |
73 |
{ |
74 |
MPI_Abort(MPI_COMM_WORLD,status); |
75 |
} |
76 |
else |
77 |
{ |
78 |
/* |
79 |
* Finalise MPI for a clean exit. |
80 |
*/ |
81 |
MPI_Finalize(); |
82 |
} |
83 |
|
84 |
Paso_MPIInfo_free( mpi_info ); |
85 |
} |
86 |
catch (std::runtime_error &e) |
87 |
{ |
88 |
std::cerr << "EXCEPTION: " << e.what() << std::endl; |
89 |
MPI_Abort(MPI_COMM_WORLD,1); |
90 |
throw; |
91 |
} |
92 |
catch (char *e) |
93 |
{ |
94 |
std::cerr << "EXCEPTION: " << e << std::endl; |
95 |
MPI_Abort(MPI_COMM_WORLD,1); |
96 |
throw; |
97 |
} |
98 |
catch (...) |
99 |
{ |
100 |
std::cerr << "EXCEPTION: " << "UNKNOWN." << std::endl; |
101 |
MPI_Abort(MPI_COMM_WORLD,1); |
102 |
throw; |
103 |
} |
104 |
|
105 |
return status; |
106 |
} |
107 |
|
108 |
#else |
109 |
int main( int argc, char **argv ) { |
110 |
printf( "Esys must be compiled with PASO_MPI defined to make the MPI version available\n\n" ); |
111 |
return 0; |
112 |
} |
113 |
#endif |