1ba9a049bSBarry Smith /* 2ba9a049bSBarry Smith This file contains Fortran stubs for PetscInitialize and Finalize. 3ba9a049bSBarry Smith */ 4ba9a049bSBarry Smith 5ba9a049bSBarry Smith /* 6ba9a049bSBarry Smith This is to prevent the Cray T3D version of MPI (University of Edinburgh) 7ba9a049bSBarry Smith from stupidly redefining MPI_INIT(). They put this in to detect errors 8ba9a049bSBarry Smith in C code,but here I do want to be calling the Fortran version from a 9ba9a049bSBarry Smith C subroutine. 10ba9a049bSBarry Smith */ 11ba9a049bSBarry Smith #define T3DMPI_FORTRAN 12ba9a049bSBarry Smith #define T3EMPI_FORTRAN 13ba9a049bSBarry Smith 14af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 15ba9a049bSBarry Smith 16519f805aSKarl Rupp #if defined(PETSC_HAVE_FORTRAN_CAPS) 175906a408SBlaise Bourdin #define petscinitializef_ PETSCINITIALIZEF 18ba9a049bSBarry Smith #define petscfinalize_ PETSCFINALIZE 19ba9a049bSBarry Smith #define petscend_ PETSCEND 20ba9a049bSBarry Smith #define iargc_ IARGC 21ba9a049bSBarry Smith #define getarg_ GETARG 22ba9a049bSBarry Smith #define mpi_init_ MPI_INIT 235ea309f3SBarry Smith #define petscgetcomm_ PETSCGETCOMM 24541b5888SSatish Balay #define petsccommandargumentcount_ PETSCCOMMANDARGUMENTCOUNT 25541b5888SSatish Balay #define petscgetcommandargument_ PETSCGETCOMMANDARGUMENT 26ba9a049bSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 275906a408SBlaise Bourdin #define petscinitializef_ petscinitializef 28ba9a049bSBarry Smith #define petscfinalize_ petscfinalize 29ba9a049bSBarry Smith #define petscend_ petscend 30ba9a049bSBarry Smith #define mpi_init_ mpi_init 31ba9a049bSBarry Smith #define iargc_ iargc 32ba9a049bSBarry Smith #define getarg_ getarg 335ea309f3SBarry Smith #define petscgetcomm_ petscgetcomm 34541b5888SSatish Balay #define petsccommandargumentcount_ petsccommandargumentcount 35541b5888SSatish Balay #define petscgetcommandargument_ petscgetcommandargument 36ba9a049bSBarry Smith #endif 37ba9a049bSBarry Smith 38ba9a049bSBarry Smith #if defined(PETSC_HAVE_NAGF90) 39ba9a049bSBarry Smith #undef iargc_ 40ba9a049bSBarry Smith #undef getarg_ 41ba9a049bSBarry Smith #define iargc_ f90_unix_MP_iargc 42ba9a049bSBarry Smith #define getarg_ f90_unix_MP_getarg 43ba9a049bSBarry Smith #endif 44ba9a049bSBarry Smith #if defined(PETSC_USE_NARGS) /* Digital Fortran */ 45ba9a049bSBarry Smith #undef iargc_ 46ba9a049bSBarry Smith #undef getarg_ 47ba9a049bSBarry Smith #define iargc_ NARGS 48ba9a049bSBarry Smith #define getarg_ GETARG 49ba9a049bSBarry Smith #elif defined(PETSC_HAVE_PXFGETARG_NEW) /* cray x1 */ 50ba9a049bSBarry Smith #undef iargc_ 51ba9a049bSBarry Smith #undef getarg_ 52ba9a049bSBarry Smith #define iargc_ ipxfargc_ 53ba9a049bSBarry Smith #define getarg_ pxfgetarg_ 54ba9a049bSBarry Smith #endif 55ba9a049bSBarry Smith #if defined(PETSC_HAVE_FORTRAN_IARGC_UNDERSCORE) /* HPUX + no underscore */ 56ba9a049bSBarry Smith #undef iargc_ 57ba9a049bSBarry Smith #undef getarg_ 58ba9a049bSBarry Smith #define iargc_ iargc_ 59ba9a049bSBarry Smith #define getarg_ getarg_ 60ba9a049bSBarry Smith #endif 61541b5888SSatish Balay 62541b5888SSatish Balay #if defined(PETSC_HAVE_FORTRAN_GET_COMMAND_ARGUMENT) /* Fortran 2003 */ 63541b5888SSatish Balay #undef iargc_ 64541b5888SSatish Balay #undef getarg_ 65541b5888SSatish Balay #define iargc_ petsccommandargumentcount_ 66541b5888SSatish Balay #define getarg_ petscgetcommandargument_ 674211eb48SBarry Smith #elif defined(PETSC_HAVE__GFORTRAN_IARGC) /* gfortran from gcc4 */ 68ba9a049bSBarry Smith #undef iargc_ 69ba9a049bSBarry Smith #undef getarg_ 70ba9a049bSBarry Smith #define iargc_ _gfortran_iargc 71ba9a049bSBarry Smith #define getarg_ _gfortran_getarg_i4 72ba9a049bSBarry Smith #elif defined(PETSC_HAVE_BGL_IARGC) /* bgl g77 has different external & internal name mangling */ 73ba9a049bSBarry Smith #undef iargc_ 74ba9a049bSBarry Smith #undef getarg_ 75ba9a049bSBarry Smith #define iargc iargc_ 76ba9a049bSBarry Smith #define getarg getarg_ 77ba9a049bSBarry Smith #endif 78ba9a049bSBarry Smith 79ba9a049bSBarry Smith /* 80ba9a049bSBarry Smith The extra _ is because the f2c compiler puts an 81ba9a049bSBarry Smith extra _ at the end if the original routine name 82ba9a049bSBarry Smith contained any _. 83ba9a049bSBarry Smith */ 84ba9a049bSBarry Smith #if defined(PETSC_HAVE_FORTRAN_UNDERSCORE_UNDERSCORE) 85ba9a049bSBarry Smith #define mpi_init_ mpi_init__ 86ba9a049bSBarry Smith #endif 87ba9a049bSBarry Smith 88a7b85bbcSSatish Balay #if defined(PETSC_HAVE_MPIUNI) 89a7b85bbcSSatish Balay #if defined(mpi_init_) 90a7b85bbcSSatish Balay #undef mpi_init_ 91a7b85bbcSSatish Balay #if defined(PETSC_HAVE_FORTRAN_CAPS) 92a7b85bbcSSatish Balay #define mpi_init_ PETSC_MPI_INIT 93a7b85bbcSSatish Balay #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 94a7b85bbcSSatish Balay #define mpi_init_ petsc_mpi_init 95a7b85bbcSSatish Balay #elif defined(PETSC_HAVE_FORTRAN_UNDERSCORE_UNDERSCORE) 96a7b85bbcSSatish Balay #define mpi_init_ petsc_mpi_init__ 97a7b85bbcSSatish Balay #endif 98a7b85bbcSSatish Balay #else /* mpi_init_ */ 99a7b85bbcSSatish Balay #define mpi_init_ petsc_mpi_init_ 100a7b85bbcSSatish Balay #endif /* mpi_init_ */ 101a7b85bbcSSatish Balay #endif /* PETSC_HAVE_MPIUNI */ 102a7b85bbcSSatish Balay 10319caf8f3SSatish Balay PETSC_EXTERN void mpi_init_(int*); 10419caf8f3SSatish Balay PETSC_EXTERN void petscgetcomm_(PetscMPIInt*); 105ba9a049bSBarry Smith 106ba9a049bSBarry Smith /* 107ba9a049bSBarry Smith Different Fortran compilers handle command lines in different ways 108ba9a049bSBarry Smith */ 109541b5888SSatish Balay #if defined(PETSC_HAVE_FORTRAN_GET_COMMAND_ARGUMENT) /* Fortran 2003 - same as 'else' case */ 110a30ec4eaSSatish Balay PETSC_EXTERN int iargc_(void); 111541b5888SSatish Balay PETSC_EXTERN void getarg_(int*,char*,int); 112541b5888SSatish Balay #elif defined(PETSC_USE_NARGS) 113*3274405dSPierre Jolivet PETSC_EXTERN short __stdcall NARGS(void); 1148cc058d9SJed Brown PETSC_EXTERN void __stdcall GETARG(short*,char*,int,short *); 115ba9a049bSBarry Smith 116ba9a049bSBarry Smith #elif defined(PETSC_HAVE_PXFGETARG_NEW) 117*3274405dSPierre Jolivet PETSC_EXTERN int iargc_(void); 1188cc058d9SJed Brown PETSC_EXTERN void getarg_(int*,char*,int*,int*,int); 119ba9a049bSBarry Smith 120ba9a049bSBarry Smith #else 121*3274405dSPierre Jolivet PETSC_EXTERN int iargc_(void); 1228cc058d9SJed Brown PETSC_EXTERN void getarg_(int*,char*,int); 123ba9a049bSBarry Smith /* 124ba9a049bSBarry Smith The Cray T3D/T3E use the PXFGETARG() function 125ba9a049bSBarry Smith */ 126ba9a049bSBarry Smith #if defined(PETSC_HAVE_PXFGETARG) 1278cc058d9SJed Brown PETSC_EXTERN void PXFGETARG(int*,_fcd,int*,int*); 128ba9a049bSBarry Smith #endif 129ba9a049bSBarry Smith #endif 130ba9a049bSBarry Smith 131071fcb05SBarry Smith PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t,PetscBool,int,const char[],const char[],void**); 13295c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscFreeAlign(void*,int,const char[],const char[]); 13395c0884eSLisandro Dalcin PETSC_INTERN int PetscGlobalArgc; 13495c0884eSLisandro Dalcin PETSC_INTERN char **PetscGlobalArgs; 135ba9a049bSBarry Smith 136ba9a049bSBarry Smith /* 137a5b23f4aSJose E. Roman Reads in Fortran command line arguments and sends them to 138d5be86a5SBarry Smith all processors. 139ba9a049bSBarry Smith */ 140ba9a049bSBarry Smith 141ba9a049bSBarry Smith PetscErrorCode PETScParseFortranArgs_Private(int *argc,char ***argv) 142ba9a049bSBarry Smith { 143ba9a049bSBarry Smith #if defined(PETSC_USE_NARGS) 144ba9a049bSBarry Smith short i,flg; 145ba9a049bSBarry Smith #else 146ba9a049bSBarry Smith int i; 147ba9a049bSBarry Smith #endif 148ba9a049bSBarry Smith int warg = 256; 149ba9a049bSBarry Smith PetscMPIInt rank; 150ba9a049bSBarry Smith char *p; 151ba9a049bSBarry Smith 1529566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 153dd400576SPatrick Sanan if (rank == 0) { 154ba9a049bSBarry Smith #if defined(PETSC_HAVE_IARG_COUNT_PROGNAME) 155ba9a049bSBarry Smith *argc = iargc_(); 156ba9a049bSBarry Smith #else 157ba9a049bSBarry Smith /* most compilers do not count the program name for argv[0] */ 158ba9a049bSBarry Smith *argc = 1 + iargc_(); 159ba9a049bSBarry Smith #endif 160ba9a049bSBarry Smith } 1619566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(argc,1,MPI_INT,0,PETSC_COMM_WORLD)); 162ba9a049bSBarry Smith 163ba9a049bSBarry Smith /* PetscTrMalloc() not yet set, so don't use PetscMalloc() */ 1649566063dSJacob Faibussowitsch PetscCall(PetscMallocAlign((*argc+1)*(warg*sizeof(char)+sizeof(char*)),PETSC_FALSE,0,0,0,(void**)argv)); 165ba9a049bSBarry Smith (*argv)[0] = (char*)(*argv + *argc + 1); 166ba9a049bSBarry Smith 167dd400576SPatrick Sanan if (rank == 0) { 1689566063dSJacob Faibussowitsch PetscCall(PetscMemzero((*argv)[0],(*argc)*warg*sizeof(char))); 169ba9a049bSBarry Smith for (i=0; i<*argc; i++) { 170ba9a049bSBarry Smith (*argv)[i+1] = (*argv)[i] + warg; 171541b5888SSatish Balay #if defined (PETSC_HAVE_FORTRAN_GET_COMMAND_ARGUMENT) /* same as 'else' case */ 172541b5888SSatish Balay getarg_(&i,(*argv)[i],warg); 173541b5888SSatish Balay #elif defined(PETSC_HAVE_PXFGETARG_NEW) 174ba9a049bSBarry Smith {char *tmp = (*argv)[i]; 175ba9a049bSBarry Smith int ilen; 1769566063dSJacob Faibussowitsch PetscCallFortranVoidFunction(getarg_(&i,tmp,&ilen,&ierr,warg)); 177a297a907SKarl Rupp tmp[ilen] = 0;} 178ba9a049bSBarry Smith #elif defined(PETSC_USE_NARGS) 179ba9a049bSBarry Smith GETARG(&i,(*argv)[i],warg,&flg); 180ba9a049bSBarry Smith #else 181ba9a049bSBarry Smith /* 182ba9a049bSBarry Smith Because the stupid #defines above define all kinds of things to getarg_ we cannot do this test 183ba9a049bSBarry Smith #elif defined(PETSC_HAVE_GETARG) 184ba9a049bSBarry Smith getarg_(&i,(*argv)[i],warg); 185ba9a049bSBarry Smith #else 186ba9a049bSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get Fortran command line arguments"); 187ba9a049bSBarry Smith */ 188ba9a049bSBarry Smith getarg_(&i,(*argv)[i],warg); 189ba9a049bSBarry Smith #endif 190ba9a049bSBarry Smith /* zero out garbage at end of each argument */ 191ba9a049bSBarry Smith p = (*argv)[i] + warg-1; 192ba9a049bSBarry Smith while (p > (*argv)[i]) { 193ba9a049bSBarry Smith if (*p == ' ') *p = 0; 194ba9a049bSBarry Smith p--; 195ba9a049bSBarry Smith } 196ba9a049bSBarry Smith } 197ba9a049bSBarry Smith } 1989566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast((*argv)[0],*argc*warg,MPI_CHAR,0,PETSC_COMM_WORLD)); 199ba9a049bSBarry Smith if (rank) { 200a297a907SKarl Rupp for (i=0; i<*argc; i++) (*argv)[i+1] = (*argv)[i] + warg; 201ba9a049bSBarry Smith } 202ba9a049bSBarry Smith return 0; 203ba9a049bSBarry Smith } 204ba9a049bSBarry Smith 205ba9a049bSBarry Smith /* -----------------------------------------------------------------------------------------------*/ 206ba9a049bSBarry Smith 207*3274405dSPierre Jolivet PETSC_INTERN PetscErrorCode PetscPreMPIInit_Private(void); 2087f20dbc5SBarry Smith 20985649d77SJunchao Zhang PETSC_INTERN PetscErrorCode PetscInitFortran_Private(PetscBool readarguments,const char *filename,PetscInt len) 21085649d77SJunchao Zhang { 21185649d77SJunchao Zhang char *tmp = NULL; 21285649d77SJunchao Zhang 21385649d77SJunchao Zhang PetscFunctionBegin; 2149566063dSJacob Faibussowitsch PetscCall(PetscInitializeFortran()); 21585649d77SJunchao Zhang if (readarguments) { 2169566063dSJacob Faibussowitsch PetscCall(PETScParseFortranArgs_Private(&PetscGlobalArgc,&PetscGlobalArgs)); 21785649d77SJunchao Zhang if (filename != PETSC_NULL_CHARACTER_Fortran) { /* FIXCHAR */ 21885649d77SJunchao Zhang while ((len > 0) && (filename[len-1] == ' ')) len--; 2199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len+1,&tmp)); 2209566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(tmp,filename,len+1)); 22185649d77SJunchao Zhang } 2229566063dSJacob Faibussowitsch PetscCall(PetscOptionsInsert(NULL,&PetscGlobalArgc,&PetscGlobalArgs,tmp)); 2239566063dSJacob Faibussowitsch PetscCall(PetscFree(tmp)); /* FREECHAR */ 22485649d77SJunchao Zhang } 22585649d77SJunchao Zhang PetscFunctionReturn(0); 22685649d77SJunchao Zhang } 22785649d77SJunchao Zhang 228ba9a049bSBarry Smith /* 229ba9a049bSBarry Smith petscinitialize - Version called from Fortran. 230ba9a049bSBarry Smith 231811af0c4SBarry Smith Note: 232ba9a049bSBarry Smith Since this is called from Fortran it does not return error codes 233ba9a049bSBarry Smith 234ba9a049bSBarry Smith */ 2355906a408SBlaise Bourdin PETSC_EXTERN void petscinitializef_(char* filename,char* help,PetscBool *readarguments,PetscErrorCode *ierr,PETSC_FORTRAN_CHARLEN_T len,PETSC_FORTRAN_CHARLEN_T helplen) 236ba9a049bSBarry Smith { 2374b60c348SBarry Smith int j,i; 238ba9a049bSBarry Smith #if defined (PETSC_USE_NARGS) 2394b60c348SBarry Smith short flg; 240ba9a049bSBarry Smith #endif 241ba9a049bSBarry Smith int flag; 24285649d77SJunchao Zhang char name[256] = {0}; 243ba9a049bSBarry Smith PetscMPIInt f_petsc_comm_world; 244ba9a049bSBarry Smith 245ba9a049bSBarry Smith if (PetscInitializeCalled) {*ierr = 0; return;} 246ba9a049bSBarry Smith i = 0; 247541b5888SSatish Balay #if defined (PETSC_HAVE_FORTRAN_GET_COMMAND_ARGUMENT) /* same as 'else' case */ 2484b60c348SBarry Smith getarg_(&i,name,sizeof(name)); 249541b5888SSatish Balay #elif defined (PETSC_HAVE_PXFGETARG_NEW) 250ba9a049bSBarry Smith { int ilen,sierr; 251ba9a049bSBarry Smith getarg_(&i,name,&ilen,&sierr,256); 252a297a907SKarl Rupp if (sierr) PetscStrncpy(name,"Unknown Name",256); 253a297a907SKarl Rupp else name[ilen] = 0; 254ba9a049bSBarry Smith } 255ba9a049bSBarry Smith #elif defined(PETSC_USE_NARGS) 256ba9a049bSBarry Smith GETARG(&i,name,256,&flg); 257ba9a049bSBarry Smith #else 258ba9a049bSBarry Smith getarg_(&i,name,256); 2594b60c348SBarry Smith #endif 260ba9a049bSBarry Smith /* Eliminate spaces at the end of the string */ 2619350f85dSSatish Balay for (j=sizeof(name)-2; j>=0; j--) { 262ba9a049bSBarry Smith if (name[j] != ' ') { 263ba9a049bSBarry Smith name[j+1] = 0; 264ba9a049bSBarry Smith break; 265ba9a049bSBarry Smith } 266ba9a049bSBarry Smith } 267a297a907SKarl Rupp if (j<0) PetscStrncpy(name,"Unknown Name",256); 268ba9a049bSBarry Smith 269ba9a049bSBarry Smith /* check if PETSC_COMM_WORLD is initialized by the user in fortran */ 2705ea309f3SBarry Smith petscgetcomm_(&f_petsc_comm_world); 271ba9a049bSBarry Smith MPI_Initialized(&flag); 272ba9a049bSBarry Smith if (!flag) { 273ba9a049bSBarry Smith PetscMPIInt mierr; 274ba9a049bSBarry Smith 275ba9a049bSBarry Smith if (f_petsc_comm_world) {(*PetscErrorPrintf)("You cannot set PETSC_COMM_WORLD if you have not initialized MPI first\n");return;} 2764dfee713SSatish Balay 2774dfee713SSatish Balay *ierr = PetscPreMPIInit_Private(); if (*ierr) return; 278ba9a049bSBarry Smith mpi_init_(&mierr); 279ba9a049bSBarry Smith if (mierr) { 280ba9a049bSBarry Smith *ierr = mierr; 281ba9a049bSBarry Smith (*PetscErrorPrintf)("PetscInitialize: Calling Fortran MPI_Init()\n"); 282ba9a049bSBarry Smith return; 283ba9a049bSBarry Smith } 284ba9a049bSBarry Smith PetscBeganMPI = PETSC_TRUE; 285ba9a049bSBarry Smith } 286a297a907SKarl Rupp if (f_petsc_comm_world) PETSC_COMM_WORLD = MPI_Comm_f2c(*(MPI_Fint*)&f_petsc_comm_world); /* User called MPI_INITIALIZE() and changed PETSC_COMM_WORLD */ 287a297a907SKarl Rupp else PETSC_COMM_WORLD = MPI_COMM_WORLD; 288ba9a049bSBarry Smith 28985649d77SJunchao Zhang *ierr = PetscInitialize_Common(name,filename,help,PETSC_TRUE,*readarguments,(PetscInt)len); 29085649d77SJunchao Zhang if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:PetscInitialize_Common\n");return;} 291ba9a049bSBarry Smith } 292ba9a049bSBarry Smith 29319caf8f3SSatish Balay PETSC_EXTERN void petscfinalize_(PetscErrorCode *ierr) 294ba9a049bSBarry Smith { 295ba9a049bSBarry Smith #if defined(PETSC_HAVE_SUNMATHPRO) 296ba9a049bSBarry Smith extern void standard_arithmetic(); 297ba9a049bSBarry Smith standard_arithmetic(); 298ba9a049bSBarry Smith #endif 299ba9a049bSBarry Smith /* was malloced with PetscMallocAlign() so free the same way */ 300efca3c55SSatish Balay *ierr = PetscFreeAlign(PetscGlobalArgs,0,0,0);if (*ierr) {(*PetscErrorPrintf)("PetscFinalize:Freeing args\n");return;} 301ba9a049bSBarry Smith 302ba9a049bSBarry Smith *ierr = PetscFinalize(); 303ba9a049bSBarry Smith } 304ba9a049bSBarry Smith 30519caf8f3SSatish Balay PETSC_EXTERN void petscend_(PetscErrorCode *ierr) 306ba9a049bSBarry Smith { 307ba9a049bSBarry Smith #if defined(PETSC_HAVE_SUNMATHPRO) 308ba9a049bSBarry Smith extern void standard_arithmetic(); 309ba9a049bSBarry Smith standard_arithmetic(); 310ba9a049bSBarry Smith #endif 311ba9a049bSBarry Smith 312ba9a049bSBarry Smith *ierr = PetscEnd(); 313ba9a049bSBarry Smith } 314