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) 1138cc058d9SJed Brown PETSC_EXTERN short __stdcall NARGS(); 1148cc058d9SJed Brown PETSC_EXTERN void __stdcall GETARG(short*,char*,int,short *); 115ba9a049bSBarry Smith 116ba9a049bSBarry Smith #elif defined(PETSC_HAVE_PXFGETARG_NEW) 1178cc058d9SJed Brown PETSC_EXTERN int iargc_(); 1188cc058d9SJed Brown PETSC_EXTERN void getarg_(int*,char*,int*,int*,int); 119ba9a049bSBarry Smith 120ba9a049bSBarry Smith #else 1218cc058d9SJed Brown PETSC_EXTERN int iargc_(); 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 PetscErrorCode ierr; 149ba9a049bSBarry Smith int warg = 256; 150ba9a049bSBarry Smith PetscMPIInt rank; 151ba9a049bSBarry Smith char *p; 152ba9a049bSBarry Smith 153ffc4695bSBarry Smith ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRMPI(ierr); 154dd400576SPatrick Sanan if (rank == 0) { 155ba9a049bSBarry Smith #if defined(PETSC_HAVE_IARG_COUNT_PROGNAME) 156ba9a049bSBarry Smith *argc = iargc_(); 157ba9a049bSBarry Smith #else 158ba9a049bSBarry Smith /* most compilers do not count the program name for argv[0] */ 159ba9a049bSBarry Smith *argc = 1 + iargc_(); 160ba9a049bSBarry Smith #endif 161ba9a049bSBarry Smith } 162ffc4695bSBarry Smith ierr = MPI_Bcast(argc,1,MPI_INT,0,PETSC_COMM_WORLD);CHKERRMPI(ierr); 163ba9a049bSBarry Smith 164ba9a049bSBarry Smith /* PetscTrMalloc() not yet set, so don't use PetscMalloc() */ 165071fcb05SBarry Smith ierr = PetscMallocAlign((*argc+1)*(warg*sizeof(char)+sizeof(char*)),PETSC_FALSE,0,0,0,(void**)argv);CHKERRQ(ierr); 166ba9a049bSBarry Smith (*argv)[0] = (char*)(*argv + *argc + 1); 167ba9a049bSBarry Smith 168dd400576SPatrick Sanan if (rank == 0) { 169ba9a049bSBarry Smith ierr = PetscMemzero((*argv)[0],(*argc)*warg*sizeof(char));CHKERRQ(ierr); 170ba9a049bSBarry Smith for (i=0; i<*argc; i++) { 171ba9a049bSBarry Smith (*argv)[i+1] = (*argv)[i] + warg; 172541b5888SSatish Balay #if defined (PETSC_HAVE_FORTRAN_GET_COMMAND_ARGUMENT) /* same as 'else' case */ 173541b5888SSatish Balay getarg_(&i,(*argv)[i],warg); 174541b5888SSatish Balay #elif defined(PETSC_HAVE_PXFGETARG_NEW) 175ba9a049bSBarry Smith {char *tmp = (*argv)[i]; 176ba9a049bSBarry Smith int ilen; 177ba9a049bSBarry Smith getarg_(&i,tmp,&ilen,&ierr,warg);CHKERRQ(ierr); 178a297a907SKarl Rupp tmp[ilen] = 0;} 179ba9a049bSBarry Smith #elif defined(PETSC_USE_NARGS) 180ba9a049bSBarry Smith GETARG(&i,(*argv)[i],warg,&flg); 181ba9a049bSBarry Smith #else 182ba9a049bSBarry Smith /* 183ba9a049bSBarry Smith Because the stupid #defines above define all kinds of things to getarg_ we cannot do this test 184ba9a049bSBarry Smith #elif defined(PETSC_HAVE_GETARG) 185ba9a049bSBarry Smith getarg_(&i,(*argv)[i],warg); 186ba9a049bSBarry Smith #else 187ba9a049bSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get Fortran command line arguments"); 188ba9a049bSBarry Smith */ 189ba9a049bSBarry Smith getarg_(&i,(*argv)[i],warg); 190ba9a049bSBarry Smith #endif 191ba9a049bSBarry Smith /* zero out garbage at end of each argument */ 192ba9a049bSBarry Smith p = (*argv)[i] + warg-1; 193ba9a049bSBarry Smith while (p > (*argv)[i]) { 194ba9a049bSBarry Smith if (*p == ' ') *p = 0; 195ba9a049bSBarry Smith p--; 196ba9a049bSBarry Smith } 197ba9a049bSBarry Smith } 198ba9a049bSBarry Smith } 199ffc4695bSBarry Smith ierr = MPI_Bcast((*argv)[0],*argc*warg,MPI_CHAR,0,PETSC_COMM_WORLD);CHKERRMPI(ierr); 200ba9a049bSBarry Smith if (rank) { 201a297a907SKarl Rupp for (i=0; i<*argc; i++) (*argv)[i+1] = (*argv)[i] + warg; 202ba9a049bSBarry Smith } 203ba9a049bSBarry Smith return 0; 204ba9a049bSBarry Smith } 205ba9a049bSBarry Smith 206ba9a049bSBarry Smith /* -----------------------------------------------------------------------------------------------*/ 207ba9a049bSBarry Smith 2084dfee713SSatish Balay PETSC_INTERN PetscErrorCode PetscPreMPIInit_Private(); 2097f20dbc5SBarry Smith 210*85649d77SJunchao Zhang PETSC_INTERN PetscErrorCode PetscInitFortran_Private(PetscBool readarguments,const char *filename,PetscInt len) 211*85649d77SJunchao Zhang { 212*85649d77SJunchao Zhang PetscErrorCode ierr; 213*85649d77SJunchao Zhang char *tmp = NULL; 214*85649d77SJunchao Zhang 215*85649d77SJunchao Zhang PetscFunctionBegin; 216*85649d77SJunchao Zhang ierr = PetscInitializeFortran();CHKERRQ(ierr); 217*85649d77SJunchao Zhang if (readarguments) { 218*85649d77SJunchao Zhang ierr = PETScParseFortranArgs_Private(&PetscGlobalArgc,&PetscGlobalArgs);CHKERRQ(ierr); 219*85649d77SJunchao Zhang if (filename != PETSC_NULL_CHARACTER_Fortran) { /* FIXCHAR */ 220*85649d77SJunchao Zhang while ((len > 0) && (filename[len-1] == ' ')) len--; 221*85649d77SJunchao Zhang ierr = PetscMalloc1(len+1,&tmp);CHKERRQ(ierr); 222*85649d77SJunchao Zhang ierr = PetscStrncpy(tmp,filename,len+1);CHKERRQ(ierr); 223*85649d77SJunchao Zhang } 224*85649d77SJunchao Zhang ierr = PetscOptionsInsert(NULL,&PetscGlobalArgc,&PetscGlobalArgs,tmp);CHKERRQ(ierr); 225*85649d77SJunchao Zhang ierr = PetscFree(tmp);CHKERRQ(ierr); /* FREECHAR */ 226*85649d77SJunchao Zhang } 227*85649d77SJunchao Zhang PetscFunctionReturn(0); 228*85649d77SJunchao Zhang } 229*85649d77SJunchao Zhang 230ba9a049bSBarry Smith /* 231ba9a049bSBarry Smith petscinitialize - Version called from Fortran. 232ba9a049bSBarry Smith 233ba9a049bSBarry Smith Notes: 234ba9a049bSBarry Smith Since this is called from Fortran it does not return error codes 235ba9a049bSBarry Smith 236ba9a049bSBarry Smith */ 2375906a408SBlaise Bourdin PETSC_EXTERN void petscinitializef_(char* filename,char* help,PetscBool *readarguments,PetscErrorCode *ierr,PETSC_FORTRAN_CHARLEN_T len,PETSC_FORTRAN_CHARLEN_T helplen) 238ba9a049bSBarry Smith { 2394b60c348SBarry Smith int j,i; 240ba9a049bSBarry Smith #if defined (PETSC_USE_NARGS) 2414b60c348SBarry Smith short flg; 242ba9a049bSBarry Smith #endif 243ba9a049bSBarry Smith int flag; 244*85649d77SJunchao Zhang char name[256] = {0}; 245ba9a049bSBarry Smith PetscMPIInt f_petsc_comm_world; 246ba9a049bSBarry Smith 247ba9a049bSBarry Smith if (PetscInitializeCalled) {*ierr = 0; return;} 248ba9a049bSBarry Smith i = 0; 249541b5888SSatish Balay #if defined (PETSC_HAVE_FORTRAN_GET_COMMAND_ARGUMENT) /* same as 'else' case */ 2504b60c348SBarry Smith getarg_(&i,name,sizeof(name)); 251541b5888SSatish Balay #elif defined (PETSC_HAVE_PXFGETARG_NEW) 252ba9a049bSBarry Smith { int ilen,sierr; 253ba9a049bSBarry Smith getarg_(&i,name,&ilen,&sierr,256); 254a297a907SKarl Rupp if (sierr) PetscStrncpy(name,"Unknown Name",256); 255a297a907SKarl Rupp else name[ilen] = 0; 256ba9a049bSBarry Smith } 257ba9a049bSBarry Smith #elif defined(PETSC_USE_NARGS) 258ba9a049bSBarry Smith GETARG(&i,name,256,&flg); 259ba9a049bSBarry Smith #else 260ba9a049bSBarry Smith getarg_(&i,name,256); 2614b60c348SBarry Smith #endif 262ba9a049bSBarry Smith /* Eliminate spaces at the end of the string */ 2639350f85dSSatish Balay for (j=sizeof(name)-2; j>=0; j--) { 264ba9a049bSBarry Smith if (name[j] != ' ') { 265ba9a049bSBarry Smith name[j+1] = 0; 266ba9a049bSBarry Smith break; 267ba9a049bSBarry Smith } 268ba9a049bSBarry Smith } 269a297a907SKarl Rupp if (j<0) PetscStrncpy(name,"Unknown Name",256); 270ba9a049bSBarry Smith 271ba9a049bSBarry Smith /* check if PETSC_COMM_WORLD is initialized by the user in fortran */ 2725ea309f3SBarry Smith petscgetcomm_(&f_petsc_comm_world); 273ba9a049bSBarry Smith MPI_Initialized(&flag); 274ba9a049bSBarry Smith if (!flag) { 275ba9a049bSBarry Smith PetscMPIInt mierr; 276ba9a049bSBarry Smith 277ba9a049bSBarry Smith if (f_petsc_comm_world) {(*PetscErrorPrintf)("You cannot set PETSC_COMM_WORLD if you have not initialized MPI first\n");return;} 2784dfee713SSatish Balay 2794dfee713SSatish Balay *ierr = PetscPreMPIInit_Private(); if (*ierr) return; 280ba9a049bSBarry Smith mpi_init_(&mierr); 281ba9a049bSBarry Smith if (mierr) { 282ba9a049bSBarry Smith *ierr = mierr; 283ba9a049bSBarry Smith (*PetscErrorPrintf)("PetscInitialize: Calling Fortran MPI_Init()\n"); 284ba9a049bSBarry Smith return; 285ba9a049bSBarry Smith } 286ba9a049bSBarry Smith PetscBeganMPI = PETSC_TRUE; 287ba9a049bSBarry Smith } 288a297a907SKarl 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 */ 289a297a907SKarl Rupp else PETSC_COMM_WORLD = MPI_COMM_WORLD; 290ba9a049bSBarry Smith 291*85649d77SJunchao Zhang *ierr = PetscInitialize_Common(name,filename,help,PETSC_TRUE,*readarguments,(PetscInt)len); 292*85649d77SJunchao Zhang if (*ierr) {(*PetscErrorPrintf)("PetscInitialize:PetscInitialize_Common\n");return;} 293ba9a049bSBarry Smith } 294ba9a049bSBarry Smith 29519caf8f3SSatish Balay PETSC_EXTERN void petscfinalize_(PetscErrorCode *ierr) 296ba9a049bSBarry Smith { 297ba9a049bSBarry Smith #if defined(PETSC_HAVE_SUNMATHPRO) 298ba9a049bSBarry Smith extern void standard_arithmetic(); 299ba9a049bSBarry Smith standard_arithmetic(); 300ba9a049bSBarry Smith #endif 301ba9a049bSBarry Smith /* was malloced with PetscMallocAlign() so free the same way */ 302efca3c55SSatish Balay *ierr = PetscFreeAlign(PetscGlobalArgs,0,0,0);if (*ierr) {(*PetscErrorPrintf)("PetscFinalize:Freeing args\n");return;} 303ba9a049bSBarry Smith 304ba9a049bSBarry Smith *ierr = PetscFinalize(); 305ba9a049bSBarry Smith } 306ba9a049bSBarry Smith 30719caf8f3SSatish Balay PETSC_EXTERN void petscend_(PetscErrorCode *ierr) 308ba9a049bSBarry Smith { 309ba9a049bSBarry Smith #if defined(PETSC_HAVE_SUNMATHPRO) 310ba9a049bSBarry Smith extern void standard_arithmetic(); 311ba9a049bSBarry Smith standard_arithmetic(); 312ba9a049bSBarry Smith #endif 313ba9a049bSBarry Smith 314ba9a049bSBarry Smith *ierr = PetscEnd(); 315ba9a049bSBarry Smith } 316