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 mpi_init_ MPI_INIT 215ea309f3SBarry Smith #define petscgetcomm_ PETSCGETCOMM 22541b5888SSatish Balay #define petsccommandargumentcount_ PETSCCOMMANDARGUMENTCOUNT 23541b5888SSatish Balay #define petscgetcommandargument_ PETSCGETCOMMANDARGUMENT 24ba9a049bSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 255906a408SBlaise Bourdin #define petscinitializef_ petscinitializef 26ba9a049bSBarry Smith #define petscfinalize_ petscfinalize 27ba9a049bSBarry Smith #define petscend_ petscend 28ba9a049bSBarry Smith #define mpi_init_ mpi_init 295ea309f3SBarry Smith #define petscgetcomm_ petscgetcomm 30541b5888SSatish Balay #define petsccommandargumentcount_ petsccommandargumentcount 31541b5888SSatish Balay #define petscgetcommandargument_ petscgetcommandargument 32ba9a049bSBarry Smith #endif 33ba9a049bSBarry Smith 34ba9a049bSBarry Smith /* 35ba9a049bSBarry Smith The extra _ is because the f2c compiler puts an 36ba9a049bSBarry Smith extra _ at the end if the original routine name 37ba9a049bSBarry Smith contained any _. 38ba9a049bSBarry Smith */ 39ba9a049bSBarry Smith #if defined(PETSC_HAVE_FORTRAN_UNDERSCORE_UNDERSCORE) 40ba9a049bSBarry Smith #define mpi_init_ mpi_init__ 41ba9a049bSBarry Smith #endif 42ba9a049bSBarry Smith 43a7b85bbcSSatish Balay #if defined(PETSC_HAVE_MPIUNI) 44a7b85bbcSSatish Balay #if defined(mpi_init_) 45a7b85bbcSSatish Balay #undef mpi_init_ 46a7b85bbcSSatish Balay #if defined(PETSC_HAVE_FORTRAN_CAPS) 47a7b85bbcSSatish Balay #define mpi_init_ PETSC_MPI_INIT 48a7b85bbcSSatish Balay #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 49a7b85bbcSSatish Balay #define mpi_init_ petsc_mpi_init 50a7b85bbcSSatish Balay #elif defined(PETSC_HAVE_FORTRAN_UNDERSCORE_UNDERSCORE) 51a7b85bbcSSatish Balay #define mpi_init_ petsc_mpi_init__ 52a7b85bbcSSatish Balay #endif 53a7b85bbcSSatish Balay #else /* mpi_init_ */ 54a7b85bbcSSatish Balay #define mpi_init_ petsc_mpi_init_ 55a7b85bbcSSatish Balay #endif /* mpi_init_ */ 56a7b85bbcSSatish Balay #endif /* PETSC_HAVE_MPIUNI */ 57a7b85bbcSSatish Balay 5819caf8f3SSatish Balay PETSC_EXTERN void mpi_init_(int *); 5919caf8f3SSatish Balay PETSC_EXTERN void petscgetcomm_(PetscMPIInt *); 60ba9a049bSBarry Smith 61ba9a049bSBarry Smith /* 62ba9a049bSBarry Smith Different Fortran compilers handle command lines in different ways 63ba9a049bSBarry Smith */ 64*8d35c829SSatish Balay PETSC_EXTERN int petsccommandargumentcount_(void); 65*8d35c829SSatish Balay PETSC_EXTERN void petscgetcommandargument_(int *, char *, PETSC_FORTRAN_CHARLEN_T); 66071fcb05SBarry Smith PETSC_EXTERN PetscErrorCode PetscMallocAlign(size_t, PetscBool, int, const char[], const char[], void **); 6795c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscFreeAlign(void *, int, const char[], const char[]); 6895c0884eSLisandro Dalcin PETSC_INTERN int PetscGlobalArgc; 6995c0884eSLisandro Dalcin PETSC_INTERN char **PetscGlobalArgs; 70ba9a049bSBarry Smith 71ba9a049bSBarry Smith /* 72a5b23f4aSJose E. Roman Reads in Fortran command line arguments and sends them to 73d5be86a5SBarry Smith all processors. 74ba9a049bSBarry Smith */ 75ba9a049bSBarry Smith 76ba9a049bSBarry Smith PetscErrorCode PETScParseFortranArgs_Private(int *argc, char ***argv) 77ba9a049bSBarry Smith { 78ba9a049bSBarry Smith int i; 79ba9a049bSBarry Smith int warg = 256; 80ba9a049bSBarry Smith PetscMPIInt rank; 81ba9a049bSBarry Smith char *p; 82ba9a049bSBarry Smith 839566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 84*8d35c829SSatish Balay if (rank == 0) { *argc = 1 + petsccommandargumentcount_(); } 859566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(argc, 1, MPI_INT, 0, PETSC_COMM_WORLD)); 86ba9a049bSBarry Smith 87ba9a049bSBarry Smith /* PetscTrMalloc() not yet set, so don't use PetscMalloc() */ 88dfef5ea7SSatish Balay PetscCall(PetscMallocAlign((*argc + 1) * (warg * sizeof(char) + sizeof(char *)), PETSC_FALSE, 0, NULL, NULL, (void **)argv)); 89ba9a049bSBarry Smith (*argv)[0] = (char *)(*argv + *argc + 1); 90ba9a049bSBarry Smith 91dd400576SPatrick Sanan if (rank == 0) { 929566063dSJacob Faibussowitsch PetscCall(PetscMemzero((*argv)[0], (*argc) * warg * sizeof(char))); 93ba9a049bSBarry Smith for (i = 0; i < *argc; i++) { 94ba9a049bSBarry Smith (*argv)[i + 1] = (*argv)[i] + warg; 95*8d35c829SSatish Balay petscgetcommandargument_(&i, (*argv)[i], warg); 96ba9a049bSBarry Smith /* zero out garbage at end of each argument */ 97ba9a049bSBarry Smith p = (*argv)[i] + warg - 1; 98ba9a049bSBarry Smith while (p > (*argv)[i]) { 99ba9a049bSBarry Smith if (*p == ' ') *p = 0; 100ba9a049bSBarry Smith p--; 101ba9a049bSBarry Smith } 102ba9a049bSBarry Smith } 103ba9a049bSBarry Smith } 1049566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast((*argv)[0], *argc * warg, MPI_CHAR, 0, PETSC_COMM_WORLD)); 105ba9a049bSBarry Smith if (rank) { 106a297a907SKarl Rupp for (i = 0; i < *argc; i++) (*argv)[i + 1] = (*argv)[i] + warg; 107ba9a049bSBarry Smith } 1083ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 109ba9a049bSBarry Smith } 110ba9a049bSBarry Smith 111ba9a049bSBarry Smith /* -----------------------------------------------------------------------------------------------*/ 112ba9a049bSBarry Smith 1133274405dSPierre Jolivet PETSC_INTERN PetscErrorCode PetscPreMPIInit_Private(void); 1147f20dbc5SBarry Smith 11585649d77SJunchao Zhang PETSC_INTERN PetscErrorCode PetscInitFortran_Private(PetscBool readarguments, const char *filename, PetscInt len) 11685649d77SJunchao Zhang { 11785649d77SJunchao Zhang char *tmp = NULL; 11885649d77SJunchao Zhang 11985649d77SJunchao Zhang PetscFunctionBegin; 1209566063dSJacob Faibussowitsch PetscCall(PetscInitializeFortran()); 12185649d77SJunchao Zhang if (readarguments) { 1229566063dSJacob Faibussowitsch PetscCall(PETScParseFortranArgs_Private(&PetscGlobalArgc, &PetscGlobalArgs)); 12385649d77SJunchao Zhang if (filename != PETSC_NULL_CHARACTER_Fortran) { /* FIXCHAR */ 12485649d77SJunchao Zhang while ((len > 0) && (filename[len - 1] == ' ')) len--; 1259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(len + 1, &tmp)); 1269566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(tmp, filename, len + 1)); 12785649d77SJunchao Zhang } 1289566063dSJacob Faibussowitsch PetscCall(PetscOptionsInsert(NULL, &PetscGlobalArgc, &PetscGlobalArgs, tmp)); 1299566063dSJacob Faibussowitsch PetscCall(PetscFree(tmp)); /* FREECHAR */ 13085649d77SJunchao Zhang } 1313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13285649d77SJunchao Zhang } 13385649d77SJunchao Zhang 134ba9a049bSBarry Smith /* 135ba9a049bSBarry Smith petscinitialize - Version called from Fortran. 136ba9a049bSBarry Smith 137811af0c4SBarry Smith Note: 138ba9a049bSBarry Smith Since this is called from Fortran it does not return error codes 139ba9a049bSBarry Smith 140ba9a049bSBarry Smith */ 1415906a408SBlaise Bourdin PETSC_EXTERN void petscinitializef_(char *filename, char *help, PetscBool *readarguments, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len, PETSC_FORTRAN_CHARLEN_T helplen) 142ba9a049bSBarry Smith { 1434b60c348SBarry Smith int j, i; 144ba9a049bSBarry Smith int flag; 14585649d77SJunchao Zhang char name[256] = {0}; 146ba9a049bSBarry Smith PetscMPIInt f_petsc_comm_world; 147ba9a049bSBarry Smith 1483ba16761SJacob Faibussowitsch *ierr = PETSC_SUCCESS; 1493ba16761SJacob Faibussowitsch if (PetscInitializeCalled) return; 150ba9a049bSBarry Smith i = 0; 151*8d35c829SSatish Balay petscgetcommandargument_(&i, name, sizeof(name)); 152ba9a049bSBarry Smith /* Eliminate spaces at the end of the string */ 1539350f85dSSatish Balay for (j = sizeof(name) - 2; j >= 0; j--) { 154ba9a049bSBarry Smith if (name[j] != ' ') { 155ba9a049bSBarry Smith name[j + 1] = 0; 156ba9a049bSBarry Smith break; 157ba9a049bSBarry Smith } 158ba9a049bSBarry Smith } 1593ba16761SJacob Faibussowitsch if (j < 0) { 1603ba16761SJacob Faibussowitsch *ierr = PetscStrncpy(name, "Unknown Name", 256); 1613ba16761SJacob Faibussowitsch if (*ierr) return; 1623ba16761SJacob Faibussowitsch } 163ba9a049bSBarry Smith 164dd01b7e5SBarry Smith /* check if PETSC_COMM_WORLD is initialized by the user in Fortran */ 1655ea309f3SBarry Smith petscgetcomm_(&f_petsc_comm_world); 166ba9a049bSBarry Smith MPI_Initialized(&flag); 167ba9a049bSBarry Smith if (!flag) { 168ba9a049bSBarry Smith PetscMPIInt mierr; 169ba9a049bSBarry Smith 1703ba16761SJacob Faibussowitsch if (f_petsc_comm_world) { 1713ba16761SJacob Faibussowitsch *ierr = (*PetscErrorPrintf)("You cannot set PETSC_COMM_WORLD if you have not initialized MPI first\n"); 1723ba16761SJacob Faibussowitsch return; 1733ba16761SJacob Faibussowitsch } 1744dfee713SSatish Balay 1753ba16761SJacob Faibussowitsch *ierr = PetscPreMPIInit_Private(); 1763ba16761SJacob Faibussowitsch if (*ierr) return; 177ba9a049bSBarry Smith mpi_init_(&mierr); 178ba9a049bSBarry Smith if (mierr) { 1793ba16761SJacob Faibussowitsch *ierr = (*PetscErrorPrintf)("PetscInitialize: Calling Fortran MPI_Init()\n"); 1803ba16761SJacob Faibussowitsch *ierr = (PetscErrorCode)mierr; 181ba9a049bSBarry Smith return; 182ba9a049bSBarry Smith } 183ba9a049bSBarry Smith PetscBeganMPI = PETSC_TRUE; 184ba9a049bSBarry Smith } 185a297a907SKarl 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 */ 186a297a907SKarl Rupp else PETSC_COMM_WORLD = MPI_COMM_WORLD; 187ba9a049bSBarry Smith 18885649d77SJunchao Zhang *ierr = PetscInitialize_Common(name, filename, help, PETSC_TRUE, *readarguments, (PetscInt)len); 1893ba16761SJacob Faibussowitsch if (*ierr) { 1903ba16761SJacob Faibussowitsch (void)(*PetscErrorPrintf)("PetscInitialize:PetscInitialize_Common\n"); 1913ba16761SJacob Faibussowitsch return; 1923ba16761SJacob Faibussowitsch } 193ba9a049bSBarry Smith } 194ba9a049bSBarry Smith 19519caf8f3SSatish Balay PETSC_EXTERN void petscfinalize_(PetscErrorCode *ierr) 196ba9a049bSBarry Smith { 197ba9a049bSBarry Smith /* was malloced with PetscMallocAlign() so free the same way */ 198dfef5ea7SSatish Balay *ierr = PetscFreeAlign(PetscGlobalArgs, 0, NULL, NULL); 1993ba16761SJacob Faibussowitsch if (*ierr) { 2003ba16761SJacob Faibussowitsch (void)(*PetscErrorPrintf)("PetscFinalize:Freeing args\n"); 2013ba16761SJacob Faibussowitsch return; 2023ba16761SJacob Faibussowitsch } 203ba9a049bSBarry Smith 204ba9a049bSBarry Smith *ierr = PetscFinalize(); 205ba9a049bSBarry Smith } 206ba9a049bSBarry Smith 20719caf8f3SSatish Balay PETSC_EXTERN void petscend_(PetscErrorCode *ierr) 208ba9a049bSBarry Smith { 209ba9a049bSBarry Smith *ierr = PetscEnd(); 210ba9a049bSBarry Smith } 211