1*ba9a049bSBarry Smith /* 2*ba9a049bSBarry Smith This file contains Fortran stubs for PetscInitialize and Finalize. 3*ba9a049bSBarry Smith */ 4*ba9a049bSBarry Smith 5*ba9a049bSBarry Smith /* 6*ba9a049bSBarry Smith This is to prevent the Cray T3D version of MPI (University of Edinburgh) 7*ba9a049bSBarry Smith from stupidly redefining MPI_INIT(). They put this in to detect errors 8*ba9a049bSBarry Smith in C code,but here I do want to be calling the Fortran version from a 9*ba9a049bSBarry Smith C subroutine. 10*ba9a049bSBarry Smith */ 11*ba9a049bSBarry Smith #define T3DMPI_FORTRAN 12*ba9a049bSBarry Smith #define T3EMPI_FORTRAN 13*ba9a049bSBarry Smith 14*ba9a049bSBarry Smith #include <petsc-private/fortranimpl.h> 15*ba9a049bSBarry Smith 16*ba9a049bSBarry Smith #if defined(PETSC_HAVE_CUSP) 17*ba9a049bSBarry Smith #include <cublas.h> 18*ba9a049bSBarry Smith #endif 19*ba9a049bSBarry Smith #include <petscthreadcomm.h> 20*ba9a049bSBarry Smith 21*ba9a049bSBarry Smith extern PetscBool PetscBeganMPI; 22*ba9a049bSBarry Smith 23*ba9a049bSBarry Smith extern PetscBool PetscHMPIWorker; 24*ba9a049bSBarry Smith 25*ba9a049bSBarry Smith #ifdef PETSC_HAVE_FORTRAN_CAPS 26*ba9a049bSBarry Smith #define petscinitialize_ PETSCINITIALIZE 27*ba9a049bSBarry Smith #define petscfinalize_ PETSCFINALIZE 28*ba9a049bSBarry Smith #define petscend_ PETSCEND 29*ba9a049bSBarry Smith #define iargc_ IARGC 30*ba9a049bSBarry Smith #define getarg_ GETARG 31*ba9a049bSBarry Smith #define mpi_init_ MPI_INIT 32*ba9a049bSBarry Smith #define petscgetcommoncomm_ PETSCGETCOMMONCOMM 33*ba9a049bSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 34*ba9a049bSBarry Smith #define petscinitialize_ petscinitialize 35*ba9a049bSBarry Smith #define petscfinalize_ petscfinalize 36*ba9a049bSBarry Smith #define petscend_ petscend 37*ba9a049bSBarry Smith #define mpi_init_ mpi_init 38*ba9a049bSBarry Smith #define iargc_ iargc 39*ba9a049bSBarry Smith #define getarg_ getarg 40*ba9a049bSBarry Smith #define petscgetcommoncomm_ petscgetcommoncomm 41*ba9a049bSBarry Smith #endif 42*ba9a049bSBarry Smith 43*ba9a049bSBarry Smith #if defined(PETSC_HAVE_NAGF90) 44*ba9a049bSBarry Smith #undef iargc_ 45*ba9a049bSBarry Smith #undef getarg_ 46*ba9a049bSBarry Smith #define iargc_ f90_unix_MP_iargc 47*ba9a049bSBarry Smith #define getarg_ f90_unix_MP_getarg 48*ba9a049bSBarry Smith #endif 49*ba9a049bSBarry Smith #if defined(PETSC_USE_NARGS) /* Digital Fortran */ 50*ba9a049bSBarry Smith #undef iargc_ 51*ba9a049bSBarry Smith #undef getarg_ 52*ba9a049bSBarry Smith #define iargc_ NARGS 53*ba9a049bSBarry Smith #define getarg_ GETARG 54*ba9a049bSBarry Smith #elif defined (PETSC_HAVE_PXFGETARG_NEW) /* cray x1 */ 55*ba9a049bSBarry Smith #undef iargc_ 56*ba9a049bSBarry Smith #undef getarg_ 57*ba9a049bSBarry Smith #define iargc_ ipxfargc_ 58*ba9a049bSBarry Smith #define getarg_ pxfgetarg_ 59*ba9a049bSBarry Smith #endif 60*ba9a049bSBarry Smith #if defined(PETSC_HAVE_FORTRAN_IARGC_UNDERSCORE) /* HPUX + no underscore */ 61*ba9a049bSBarry Smith #undef iargc_ 62*ba9a049bSBarry Smith #undef getarg_ 63*ba9a049bSBarry Smith #define iargc_ iargc_ 64*ba9a049bSBarry Smith #define getarg_ getarg_ 65*ba9a049bSBarry Smith #endif 66*ba9a049bSBarry Smith #if defined(PETSC_HAVE_GFORTRAN_IARGC) /* gfortran from gcc4 */ 67*ba9a049bSBarry Smith #undef iargc_ 68*ba9a049bSBarry Smith #undef getarg_ 69*ba9a049bSBarry Smith #define iargc_ _gfortran_iargc 70*ba9a049bSBarry Smith #define getarg_ _gfortran_getarg_i4 71*ba9a049bSBarry Smith #elif defined(PETSC_HAVE_BGL_IARGC) /* bgl g77 has different external & internal name mangling */ 72*ba9a049bSBarry Smith #undef iargc_ 73*ba9a049bSBarry Smith #undef getarg_ 74*ba9a049bSBarry Smith #define iargc iargc_ 75*ba9a049bSBarry Smith #define getarg getarg_ 76*ba9a049bSBarry Smith #endif 77*ba9a049bSBarry Smith 78*ba9a049bSBarry Smith /* 79*ba9a049bSBarry Smith The extra _ is because the f2c compiler puts an 80*ba9a049bSBarry Smith extra _ at the end if the original routine name 81*ba9a049bSBarry Smith contained any _. 82*ba9a049bSBarry Smith */ 83*ba9a049bSBarry Smith #if defined(PETSC_HAVE_FORTRAN_UNDERSCORE_UNDERSCORE) 84*ba9a049bSBarry Smith #undef mpi_init_ 85*ba9a049bSBarry Smith #define mpi_init_ mpi_init__ 86*ba9a049bSBarry Smith #endif 87*ba9a049bSBarry Smith 88*ba9a049bSBarry Smith EXTERN_C_BEGIN 89*ba9a049bSBarry Smith extern void PETSC_STDCALL mpi_init_(int*); 90*ba9a049bSBarry Smith extern void PETSC_STDCALL petscgetcommoncomm_(PetscMPIInt*); 91*ba9a049bSBarry Smith 92*ba9a049bSBarry Smith /* 93*ba9a049bSBarry Smith Different Fortran compilers handle command lines in different ways 94*ba9a049bSBarry Smith */ 95*ba9a049bSBarry Smith #if defined(PETSC_USE_NARGS) 96*ba9a049bSBarry Smith extern short __stdcall NARGS(); 97*ba9a049bSBarry Smith extern void __stdcall GETARG(short*,char*,int,short *); 98*ba9a049bSBarry Smith 99*ba9a049bSBarry Smith #elif defined(PETSC_HAVE_FORTRAN_STDCALL) 100*ba9a049bSBarry Smith extern int PETSC_STDCALL IARGC(); 101*ba9a049bSBarry Smith extern void PETSC_STDCALL GETARG(int *,char *,int); 102*ba9a049bSBarry Smith 103*ba9a049bSBarry Smith #elif defined (PETSC_HAVE_PXFGETARG_NEW) 104*ba9a049bSBarry Smith extern int iargc_(); 105*ba9a049bSBarry Smith extern void getarg_(int*,char*,int*,int*,int); 106*ba9a049bSBarry Smith 107*ba9a049bSBarry Smith #else 108*ba9a049bSBarry Smith extern int iargc_(); 109*ba9a049bSBarry Smith extern void getarg_(int*,char*,int); 110*ba9a049bSBarry Smith /* 111*ba9a049bSBarry Smith The Cray T3D/T3E use the PXFGETARG() function 112*ba9a049bSBarry Smith */ 113*ba9a049bSBarry Smith #if defined(PETSC_HAVE_PXFGETARG) 114*ba9a049bSBarry Smith extern void PXFGETARG(int*,_fcd,int*,int*); 115*ba9a049bSBarry Smith #endif 116*ba9a049bSBarry Smith #endif 117*ba9a049bSBarry Smith EXTERN_C_END 118*ba9a049bSBarry Smith 119*ba9a049bSBarry Smith #if (defined(PETSC_USE_COMPLEX) && !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX)) || defined(PETSC_USE_REAL___FLOAT128) 120*ba9a049bSBarry Smith extern MPI_Op MPIU_SUM; 121*ba9a049bSBarry Smith EXTERN_C_BEGIN 122*ba9a049bSBarry Smith extern void MPIAPI PetscSum_Local(void*,void *,PetscMPIInt *,MPI_Datatype *); 123*ba9a049bSBarry Smith EXTERN_C_END 124*ba9a049bSBarry Smith #endif 125*ba9a049bSBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 126*ba9a049bSBarry Smith EXTERN_C_BEGIN 127*ba9a049bSBarry Smith void MPIAPI PetscSum_Local(void *,void *,PetscMPIInt *,MPI_Datatype *); 128*ba9a049bSBarry Smith void MPIAPI PetscMax_Local(void *,void *,PetscMPIInt *,MPI_Datatype *); 129*ba9a049bSBarry Smith void MPIAPI PetscMin_Local(void *,void *,PetscMPIInt *,MPI_Datatype *); 130*ba9a049bSBarry Smith EXTERN_C_END 131*ba9a049bSBarry Smith #endif 132*ba9a049bSBarry Smith 133*ba9a049bSBarry Smith extern MPI_Op PetscMaxSum_Op; 134*ba9a049bSBarry Smith 135*ba9a049bSBarry Smith EXTERN_C_BEGIN 136*ba9a049bSBarry Smith extern void MPIAPI PetscMaxSum_Local(void*,void *,PetscMPIInt *,MPI_Datatype *); 137*ba9a049bSBarry Smith extern PetscMPIInt MPIAPI Petsc_DelCounter(MPI_Comm,PetscMPIInt,void*,void*); 138*ba9a049bSBarry Smith extern PetscMPIInt MPIAPI Petsc_DelComm(MPI_Comm,PetscMPIInt,void*,void*); 139*ba9a049bSBarry Smith EXTERN_C_END 140*ba9a049bSBarry Smith 141*ba9a049bSBarry Smith extern PetscErrorCode PetscOptionsCheckInitial_Private(void); 142*ba9a049bSBarry Smith extern PetscErrorCode PetscOptionsCheckInitial_Components(void); 143*ba9a049bSBarry Smith extern PetscErrorCode PetscInitialize_DynamicLibraries(void); 144*ba9a049bSBarry Smith #if defined(PETSC_USE_LOG) 145*ba9a049bSBarry Smith extern PetscErrorCode PetscLogBegin_Private(void); 146*ba9a049bSBarry Smith #endif 147*ba9a049bSBarry Smith extern PetscErrorCode PetscMallocAlign(size_t,int,const char[],const char[],const char[],void**); 148*ba9a049bSBarry Smith extern PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[],const char[]); 149*ba9a049bSBarry Smith extern int PetscGlobalArgc; 150*ba9a049bSBarry Smith extern char **PetscGlobalArgs; 151*ba9a049bSBarry Smith 152*ba9a049bSBarry Smith /* 153*ba9a049bSBarry Smith Reads in Fortran command line argments and sends them to 154*ba9a049bSBarry Smith all processors and adds them to Options database. 155*ba9a049bSBarry Smith */ 156*ba9a049bSBarry Smith 157*ba9a049bSBarry Smith PetscErrorCode PETScParseFortranArgs_Private(int *argc,char ***argv) 158*ba9a049bSBarry Smith { 159*ba9a049bSBarry Smith #if defined (PETSC_USE_NARGS) 160*ba9a049bSBarry Smith short i,flg; 161*ba9a049bSBarry Smith #else 162*ba9a049bSBarry Smith int i; 163*ba9a049bSBarry Smith #endif 164*ba9a049bSBarry Smith PetscErrorCode ierr; 165*ba9a049bSBarry Smith int warg = 256; 166*ba9a049bSBarry Smith PetscMPIInt rank; 167*ba9a049bSBarry Smith char *p; 168*ba9a049bSBarry Smith 169*ba9a049bSBarry Smith ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); 170*ba9a049bSBarry Smith if (!rank) { 171*ba9a049bSBarry Smith #if defined (PETSC_HAVE_IARG_COUNT_PROGNAME) 172*ba9a049bSBarry Smith *argc = iargc_(); 173*ba9a049bSBarry Smith #else 174*ba9a049bSBarry Smith /* most compilers do not count the program name for argv[0] */ 175*ba9a049bSBarry Smith *argc = 1 + iargc_(); 176*ba9a049bSBarry Smith #endif 177*ba9a049bSBarry Smith } 178*ba9a049bSBarry Smith ierr = MPI_Bcast(argc,1,MPI_INT,0,PETSC_COMM_WORLD);CHKERRQ(ierr); 179*ba9a049bSBarry Smith 180*ba9a049bSBarry Smith /* PetscTrMalloc() not yet set, so don't use PetscMalloc() */ 181*ba9a049bSBarry Smith ierr = PetscMallocAlign((*argc+1)*(warg*sizeof(char)+sizeof(char*)),0,0,0,0,(void**)argv);CHKERRQ(ierr); 182*ba9a049bSBarry Smith (*argv)[0] = (char*)(*argv + *argc + 1); 183*ba9a049bSBarry Smith 184*ba9a049bSBarry Smith if (!rank) { 185*ba9a049bSBarry Smith ierr = PetscMemzero((*argv)[0],(*argc)*warg*sizeof(char));CHKERRQ(ierr); 186*ba9a049bSBarry Smith for (i=0; i<*argc; i++) { 187*ba9a049bSBarry Smith (*argv)[i+1] = (*argv)[i] + warg; 188*ba9a049bSBarry Smith #if defined (PETSC_HAVE_PXFGETARG_NEW) 189*ba9a049bSBarry Smith {char *tmp = (*argv)[i]; 190*ba9a049bSBarry Smith int ilen; 191*ba9a049bSBarry Smith getarg_(&i,tmp,&ilen,&ierr,warg);CHKERRQ(ierr); 192*ba9a049bSBarry Smith tmp[ilen] = 0; 193*ba9a049bSBarry Smith } 194*ba9a049bSBarry Smith #elif defined (PETSC_USE_NARGS) 195*ba9a049bSBarry Smith GETARG(&i,(*argv)[i],warg,&flg); 196*ba9a049bSBarry Smith #else 197*ba9a049bSBarry Smith /* 198*ba9a049bSBarry Smith Because the stupid #defines above define all kinds of things to getarg_ we cannot do this test 199*ba9a049bSBarry Smith #elif defined(PETSC_HAVE_GETARG) 200*ba9a049bSBarry Smith getarg_(&i,(*argv)[i],warg); 201*ba9a049bSBarry Smith #else 202*ba9a049bSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get Fortran command line arguments"); 203*ba9a049bSBarry Smith */ 204*ba9a049bSBarry Smith getarg_(&i,(*argv)[i],warg); 205*ba9a049bSBarry Smith #endif 206*ba9a049bSBarry Smith /* zero out garbage at end of each argument */ 207*ba9a049bSBarry Smith p = (*argv)[i] + warg-1; 208*ba9a049bSBarry Smith while (p > (*argv)[i]) { 209*ba9a049bSBarry Smith if (*p == ' ') *p = 0; 210*ba9a049bSBarry Smith p--; 211*ba9a049bSBarry Smith } 212*ba9a049bSBarry Smith } 213*ba9a049bSBarry Smith } 214*ba9a049bSBarry Smith ierr = MPI_Bcast((*argv)[0],*argc*warg,MPI_CHAR,0,PETSC_COMM_WORLD);CHKERRQ(ierr); 215*ba9a049bSBarry Smith if (rank) { 216*ba9a049bSBarry Smith for (i=0; i<*argc; i++) { 217*ba9a049bSBarry Smith (*argv)[i+1] = (*argv)[i] + warg; 218*ba9a049bSBarry Smith } 219*ba9a049bSBarry Smith } 220*ba9a049bSBarry Smith return 0; 221*ba9a049bSBarry Smith } 222*ba9a049bSBarry Smith 223*ba9a049bSBarry Smith /* -----------------------------------------------------------------------------------------------*/ 224*ba9a049bSBarry Smith 225*ba9a049bSBarry Smith extern MPI_Op PetscADMax_Op; 226*ba9a049bSBarry Smith extern MPI_Op PetscADMin_Op; 227*ba9a049bSBarry Smith EXTERN_C_BEGIN 228*ba9a049bSBarry Smith extern void MPIAPI PetscADMax_Local(void *,void *,PetscMPIInt *,MPI_Datatype *); 229*ba9a049bSBarry Smith extern void MPIAPI PetscADMin_Local(void *,void *,PetscMPIInt *,MPI_Datatype *); 230*ba9a049bSBarry Smith EXTERN_C_END 231*ba9a049bSBarry Smith 232*ba9a049bSBarry Smith 233*ba9a049bSBarry Smith EXTERN_C_BEGIN 234*ba9a049bSBarry Smith /* 235*ba9a049bSBarry Smith petscinitialize - Version called from Fortran. 236*ba9a049bSBarry Smith 237*ba9a049bSBarry Smith Notes: 238*ba9a049bSBarry Smith Since this is called from Fortran it does not return error codes 239*ba9a049bSBarry Smith 240*ba9a049bSBarry Smith */ 241*ba9a049bSBarry Smith void PETSC_STDCALL petscinitialize_(CHAR filename PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len)) 242*ba9a049bSBarry Smith { 243*ba9a049bSBarry Smith #if defined (PETSC_USE_NARGS) 244*ba9a049bSBarry Smith short flg,i; 245*ba9a049bSBarry Smith #else 246*ba9a049bSBarry Smith int i; 247*ba9a049bSBarry Smith #if !defined(PETSC_HAVE_PXFGETARG_NEW) && !defined (PETSC_HAVE_PXFGETARG_NEW) 248*ba9a049bSBarry Smith int j; 249*ba9a049bSBarry Smith #endif 250*ba9a049bSBarry Smith #endif 251*ba9a049bSBarry Smith int flag; 252*ba9a049bSBarry Smith PetscMPIInt size; 253*ba9a049bSBarry Smith char *t1,name[256],hostname[64]; 254*ba9a049bSBarry Smith PetscMPIInt f_petsc_comm_world; 255*ba9a049bSBarry Smith PetscInt nodesize; 256*ba9a049bSBarry Smith PetscBool flg; 257*ba9a049bSBarry Smith 258*ba9a049bSBarry Smith *ierr = PetscMemzero(name,256); if (*ierr) return; 259*ba9a049bSBarry Smith if (PetscInitializeCalled) {*ierr = 0; return;} 260*ba9a049bSBarry Smith 261*ba9a049bSBarry Smith /* this must be initialized in a routine, not as a constant declaration*/ 262*ba9a049bSBarry Smith PETSC_STDOUT = stdout; 263*ba9a049bSBarry Smith PETSC_STDERR = stderr; 264*ba9a049bSBarry Smith 265*ba9a049bSBarry Smith *ierr = PetscOptionsCreate(); 266*ba9a049bSBarry Smith if (*ierr) return; 267*ba9a049bSBarry Smith i = 0; 268*ba9a049bSBarry Smith #if defined (PETSC_HAVE_PXFGETARG_NEW) 269*ba9a049bSBarry Smith { int ilen,sierr; 270*ba9a049bSBarry Smith getarg_(&i,name,&ilen,&sierr,256); 271*ba9a049bSBarry Smith if (sierr) { 272*ba9a049bSBarry Smith PetscStrncpy(name,"Unknown Name",256); 273*ba9a049bSBarry Smith } else { 274*ba9a049bSBarry Smith name[ilen] = 0; 275*ba9a049bSBarry Smith } 276*ba9a049bSBarry Smith } 277*ba9a049bSBarry Smith #elif defined (PETSC_USE_NARGS) 278*ba9a049bSBarry Smith GETARG(&i,name,256,&flg); 279*ba9a049bSBarry Smith #else 280*ba9a049bSBarry Smith getarg_(&i,name,256); 281*ba9a049bSBarry Smith /* Eliminate spaces at the end of the string */ 282*ba9a049bSBarry Smith for (j=254; j>=0; j--) { 283*ba9a049bSBarry Smith if (name[j] != ' ') { 284*ba9a049bSBarry Smith name[j+1] = 0; 285*ba9a049bSBarry Smith break; 286*ba9a049bSBarry Smith } 287*ba9a049bSBarry Smith } 288*ba9a049bSBarry Smith if (j<0) { 289*ba9a049bSBarry Smith PetscStrncpy(name,"Unknown Name",256); 290*ba9a049bSBarry Smith } 291*ba9a049bSBarry Smith #endif 292*ba9a049bSBarry Smith *ierr = PetscSetProgramName(name); 293*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize: Calling PetscSetProgramName()\n");return;} 294*ba9a049bSBarry Smith 295*ba9a049bSBarry Smith /* check if PETSC_COMM_WORLD is initialized by the user in fortran */ 296*ba9a049bSBarry Smith petscgetcommoncomm_(&f_petsc_comm_world); 297*ba9a049bSBarry Smith MPI_Initialized(&flag); 298*ba9a049bSBarry Smith if (!flag) { 299*ba9a049bSBarry Smith PetscMPIInt mierr; 300*ba9a049bSBarry Smith 301*ba9a049bSBarry Smith if (f_petsc_comm_world) {(*PetscErrorPrintf)("You cannot set PETSC_COMM_WORLD if you have not initialized MPI first\n");return;} 302*ba9a049bSBarry Smith /* MPI requires calling Fortran mpi_init() if main program is Fortran */ 303*ba9a049bSBarry Smith mpi_init_(&mierr); 304*ba9a049bSBarry Smith if (mierr) { 305*ba9a049bSBarry Smith *ierr = mierr; 306*ba9a049bSBarry Smith (*PetscErrorPrintf)("PetscInitialize: Calling Fortran MPI_Init()\n"); 307*ba9a049bSBarry Smith return; 308*ba9a049bSBarry Smith } 309*ba9a049bSBarry Smith PetscBeganMPI = PETSC_TRUE; 310*ba9a049bSBarry Smith } 311*ba9a049bSBarry Smith if (f_petsc_comm_world) { /* User called MPI_INITIALIZE() and changed PETSC_COMM_WORLD */ 312*ba9a049bSBarry Smith PETSC_COMM_WORLD = MPI_Comm_f2c(*(MPI_Fint *)&f_petsc_comm_world); 313*ba9a049bSBarry Smith } else { 314*ba9a049bSBarry Smith PETSC_COMM_WORLD = MPI_COMM_WORLD; 315*ba9a049bSBarry Smith } 316*ba9a049bSBarry Smith PetscInitializeCalled = PETSC_TRUE; 317*ba9a049bSBarry Smith 318*ba9a049bSBarry Smith *ierr = PetscErrorPrintfInitialize(); 319*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize: Calling PetscErrorPrintfInitialize()\n");return;} 320*ba9a049bSBarry Smith *ierr = MPI_Comm_rank(MPI_COMM_WORLD,&PetscGlobalRank); 321*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize: Setting PetscGlobalRank\n");return;} 322*ba9a049bSBarry Smith *ierr = MPI_Comm_size(MPI_COMM_WORLD,&PetscGlobalSize); 323*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize: Setting PetscGlobalSize\n");return;} 324*ba9a049bSBarry Smith #if defined(PETSC_USE_COMPLEX) 325*ba9a049bSBarry Smith /* 326*ba9a049bSBarry Smith Initialized the global variable; this is because with 327*ba9a049bSBarry Smith shared libraries the constructors for global variables 328*ba9a049bSBarry Smith are not called; at least on IRIX. 329*ba9a049bSBarry Smith */ 330*ba9a049bSBarry Smith { 331*ba9a049bSBarry Smith #if defined(PETSC_CLANGUAGE_CXX) 332*ba9a049bSBarry Smith PetscScalar ic(0.0,1.0); 333*ba9a049bSBarry Smith PETSC_i = ic; 334*ba9a049bSBarry Smith #else 335*ba9a049bSBarry Smith PetscScalar ic; 336*ba9a049bSBarry Smith ic = 1.0*I; 337*ba9a049bSBarry Smith PETSC_i = ic; 338*ba9a049bSBarry Smith #endif 339*ba9a049bSBarry Smith } 340*ba9a049bSBarry Smith 341*ba9a049bSBarry Smith #if !defined(PETSC_HAVE_MPI_C_DOUBLE_COMPLEX) 342*ba9a049bSBarry Smith *ierr = MPI_Type_contiguous(2,MPIU_REAL,&MPIU_C_DOUBLE_COMPLEX); 343*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 344*ba9a049bSBarry Smith *ierr = MPI_Type_commit(&MPIU_C_DOUBLE_COMPLEX); 345*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 346*ba9a049bSBarry Smith *ierr = MPI_Type_contiguous(2,MPI_FLOAT,&MPIU_C_COMPLEX); 347*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 348*ba9a049bSBarry Smith *ierr = MPI_Type_commit(&MPIU_C_COMPLEX); 349*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 350*ba9a049bSBarry Smith *ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM); 351*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI ops\n");return;} 352*ba9a049bSBarry Smith #endif 353*ba9a049bSBarry Smith 354*ba9a049bSBarry Smith #endif 355*ba9a049bSBarry Smith 356*ba9a049bSBarry Smith #if defined(PETSC_USE_REAL___FLOAT128) 357*ba9a049bSBarry Smith *ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___FLOAT128); 358*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 359*ba9a049bSBarry Smith *ierr = MPI_Type_commit(&MPIU___FLOAT128); 360*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 361*ba9a049bSBarry Smith #if defined(PETSC_USE_COMPLEX) 362*ba9a049bSBarry Smith *ierr = MPI_Type_contiguous(2,MPI_DOUBLE,&MPIU___COMPLEX128); 363*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 364*ba9a049bSBarry Smith *ierr = MPI_Type_commit(&MPIU___COMPLEX128); 365*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 366*ba9a049bSBarry Smith #endif 367*ba9a049bSBarry Smith *ierr = MPI_Op_create(PetscSum_Local,1,&MPIU_SUM); 368*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI ops\n");return;} 369*ba9a049bSBarry Smith *ierr = MPI_Op_create(PetscMax_Local,1,&MPIU_MAX); 370*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI ops\n");return;} 371*ba9a049bSBarry Smith *ierr = MPI_Op_create(PetscMin_Local,1,&MPIU_MIN); 372*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI ops\n");return;} 373*ba9a049bSBarry Smith #endif 374*ba9a049bSBarry Smith 375*ba9a049bSBarry Smith /* 376*ba9a049bSBarry Smith Create the PETSc MPI reduction operator that sums of the first 377*ba9a049bSBarry Smith half of the entries and maxes the second half. 378*ba9a049bSBarry Smith */ 379*ba9a049bSBarry Smith *ierr = MPI_Op_create(PetscMaxSum_Local,1,&PetscMaxSum_Op); 380*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI ops\n");return;} 381*ba9a049bSBarry Smith 382*ba9a049bSBarry Smith *ierr = MPI_Type_contiguous(2,MPIU_SCALAR,&MPIU_2SCALAR); 383*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 384*ba9a049bSBarry Smith *ierr = MPI_Type_commit(&MPIU_2SCALAR); 385*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 386*ba9a049bSBarry Smith *ierr = MPI_Type_contiguous(2,MPIU_INT,&MPIU_2INT); 387*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 388*ba9a049bSBarry Smith *ierr = MPI_Type_commit(&MPIU_2INT); 389*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI types\n");return;} 390*ba9a049bSBarry Smith *ierr = MPI_Op_create(PetscADMax_Local,1,&PetscADMax_Op); 391*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI ops\n");return;} 392*ba9a049bSBarry Smith *ierr = MPI_Op_create(PetscADMin_Local,1,&PetscADMin_Op); 393*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI ops\n");return;} 394*ba9a049bSBarry Smith *ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelCounter,&Petsc_Counter_keyval,(void*)0); 395*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI keyvals\n");return;} 396*ba9a049bSBarry Smith *ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_InnerComm_keyval,(void*)0); 397*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI keyvals\n");return;} 398*ba9a049bSBarry Smith *ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelComm,&Petsc_OuterComm_keyval,(void*)0); 399*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating MPI keyvals\n");return;} 400*ba9a049bSBarry Smith 401*ba9a049bSBarry Smith /* 402*ba9a049bSBarry Smith PetscInitializeFortran() is called twice. Here it initializes 403*ba9a049bSBarry Smith PETSC_NULL_CHARACTER_Fortran. Below it initializes the PETSC_VIEWERs. 404*ba9a049bSBarry Smith The PETSC_VIEWERs have not been created yet, so they must be initialized 405*ba9a049bSBarry Smith below. 406*ba9a049bSBarry Smith */ 407*ba9a049bSBarry Smith PetscInitializeFortran(); 408*ba9a049bSBarry Smith PETScParseFortranArgs_Private(&PetscGlobalArgc,&PetscGlobalArgs); 409*ba9a049bSBarry Smith FIXCHAR(filename,len,t1); 410*ba9a049bSBarry Smith *ierr = PetscOptionsInsert(&PetscGlobalArgc,&PetscGlobalArgs,t1); 411*ba9a049bSBarry Smith FREECHAR(filename,t1); 412*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Creating options database\n");return;} 413*ba9a049bSBarry Smith *ierr = PetscOptionsCheckInitial_Private(); 414*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Checking initial options\n");return;} 415*ba9a049bSBarry Smith #if defined (PETSC_USE_LOG) 416*ba9a049bSBarry Smith *ierr = PetscLogBegin_Private(); 417*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize: intializing logging\n");return;} 418*ba9a049bSBarry Smith #endif 419*ba9a049bSBarry Smith *ierr = PetscInitialize_DynamicLibraries(); 420*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Initializing dynamic libraries\n");return;} 421*ba9a049bSBarry Smith 422*ba9a049bSBarry Smith *ierr = PetscInitializeFortran(); 423*ba9a049bSBarry Smith if (*ierr) { (*PetscErrorPrintf)("PetscInitialize:Setting up common block\n");return;} 424*ba9a049bSBarry Smith 425*ba9a049bSBarry Smith *ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size); 426*ba9a049bSBarry Smith if (*ierr) { (*PetscErrorPrintf)("PetscInitialize:Getting MPI_Comm_size()\n");return;} 427*ba9a049bSBarry Smith *ierr = PetscInfo1(0,"(Fortran):PETSc successfully started: procs %d\n",size); 428*ba9a049bSBarry Smith if (*ierr) { (*PetscErrorPrintf)("PetscInitialize:Calling PetscInfo()\n");return;} 429*ba9a049bSBarry Smith *ierr = PetscGetHostName(hostname,64); 430*ba9a049bSBarry Smith if (*ierr) { (*PetscErrorPrintf)("PetscInitialize:Getting hostname\n");return;} 431*ba9a049bSBarry Smith *ierr = PetscInfo1(0,"Running on machine: %s\n",hostname); 432*ba9a049bSBarry Smith if (*ierr) { (*PetscErrorPrintf)("PetscInitialize:Calling PetscInfo()\n");return;} 433*ba9a049bSBarry Smith *ierr = PetscOptionsCheckInitial_Components(); 434*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Checking initial options\n");return;} 435*ba9a049bSBarry Smith 436*ba9a049bSBarry Smith *ierr = PetscThreadCommInitializePackage(PETSC_NULL); 437*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:Calling PetscThreadCommInitialize()\n");return;} 438*ba9a049bSBarry Smith 439*ba9a049bSBarry Smith *ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_spawn_size",&nodesize,&flg); 440*ba9a049bSBarry Smith if (flg) { 441*ba9a049bSBarry Smith #if defined(PETSC_HAVE_MPI_COMM_SPAWN) 442*ba9a049bSBarry Smith *ierr = PetscHMPISpawn((PetscMPIInt) nodesize);/* worker nodes never return from here; they go directly to PetscEnd() */ 443*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:PetscHMPIS-pawn()\n");return;} 444*ba9a049bSBarry Smith #else 445*ba9a049bSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PETSc built without MPI 2 (MPI_Comm_spawn) support, use -hmpi_merge_size instead"); 446*ba9a049bSBarry Smith #endif 447*ba9a049bSBarry Smith } else { 448*ba9a049bSBarry Smith *ierr = PetscOptionsGetInt(PETSC_NULL,"-hmpi_merge_size",&nodesize,&flg); 449*ba9a049bSBarry Smith if (flg) { 450*ba9a049bSBarry Smith *ierr = PetscHMPIMerge((PetscMPIInt) nodesize,PETSC_NULL,PETSC_NULL); 451*ba9a049bSBarry Smith if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:PetscHMPIMerge()\n");return;} 452*ba9a049bSBarry Smith if (PetscHMPIWorker) { /* if worker then never enter user code */ 453*ba9a049bSBarry Smith PetscInitializeCalled = PETSC_TRUE; 454*ba9a049bSBarry Smith *ierr = PetscEnd(); 455*ba9a049bSBarry Smith } 456*ba9a049bSBarry Smith } 457*ba9a049bSBarry Smith } 458*ba9a049bSBarry Smith 459*ba9a049bSBarry Smith #if defined(PETSC_HAVE_CUDA) 460*ba9a049bSBarry Smith cublasInit(); 461*ba9a049bSBarry Smith #endif 462*ba9a049bSBarry Smith } 463*ba9a049bSBarry Smith 464*ba9a049bSBarry Smith void PETSC_STDCALL petscfinalize_(PetscErrorCode *ierr) 465*ba9a049bSBarry Smith { 466*ba9a049bSBarry Smith #if defined(PETSC_HAVE_SUNMATHPRO) 467*ba9a049bSBarry Smith extern void standard_arithmetic(); 468*ba9a049bSBarry Smith standard_arithmetic(); 469*ba9a049bSBarry Smith #endif 470*ba9a049bSBarry Smith /* was malloced with PetscMallocAlign() so free the same way */ 471*ba9a049bSBarry Smith *ierr = PetscFreeAlign(PetscGlobalArgs,0,0,0,0);if (*ierr) {(*PetscErrorPrintf)("PetscFinalize:Freeing args\n");return;} 472*ba9a049bSBarry Smith 473*ba9a049bSBarry Smith *ierr = PetscFinalize(); 474*ba9a049bSBarry Smith } 475*ba9a049bSBarry Smith 476*ba9a049bSBarry Smith void PETSC_STDCALL petscend_(PetscErrorCode *ierr) 477*ba9a049bSBarry Smith { 478*ba9a049bSBarry Smith #if defined(PETSC_HAVE_SUNMATHPRO) 479*ba9a049bSBarry Smith extern void standard_arithmetic(); 480*ba9a049bSBarry Smith standard_arithmetic(); 481*ba9a049bSBarry Smith #endif 482*ba9a049bSBarry Smith 483*ba9a049bSBarry Smith *ierr = PetscEnd(); 484*ba9a049bSBarry Smith } 485*ba9a049bSBarry Smith 486*ba9a049bSBarry Smith 487*ba9a049bSBarry Smith EXTERN_C_END 488