1 /* 2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana 3 * University Research and Technology 4 * Corporation. All rights reserved. 5 * Copyright (c) 2004-2013 The University of Tennessee and The University 6 * of Tennessee Research Foundation. All rights 7 * reserved. 8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 9 * University of Stuttgart. All rights reserved. 10 * Copyright (c) 2004-2005 The Regents of the University of California. 11 * All rights reserved. 12 * Copyright (c) 2006-2015 Cisco Systems, Inc. All rights reserved. 13 * Copyright (c) 2011-2013 Inria. All rights reserved. 14 * Copyright (c) 2011-2012 Universite Bordeaux 1 15 * Copyright (c) 2015 Research Organization for Information Science 16 * and Technology (RIST). All rights reserved. 17 * $COPYRIGHT$ 18 * 19 * Additional copyrights may follow 20 * 21 * $HEADER$ 22 */ 23 24 #ifndef OMPI_FORTRAN_BASE_CONSTANTS_H 25 #define OMPI_FORTRAN_BASE_CONSTANTS_H 26 27 #include "ompi_config.h" 28 29 #if OMPI_BUILD_FORTRAN_BINDINGS 30 /* 31 * Several variables are used to link against MPI F77 constants which 32 * correspond to addresses, e.g. MPI_BOTTOM, and are implemented via 33 * common blocks. 34 * 35 * We use common blocks so that in the C wrapper functions, we can 36 * compare the address that comes in against known addresses (e.g., if 37 * the "status" argument in MPI_RECV is the address of the common 38 * block for the fortran equivalent of MPI_STATUS_IGNORE, then we know 39 * to pass the C MPI_STATUS_IGNORE to the C MPI_Recv function). As 40 * such, we never look at the *value* of these variables (indeed, 41 * they're never actually initialized), but instead only ever look at 42 * the *address* of these variables. 43 * 44 * As such, it is not strictly necessary that the size and type of our 45 * C variables matches that of the common Fortran block variables. 46 * However, good programming form says that we should match, so we do. 47 * 48 * Note, however, that the alignments of the Fortran common block and 49 * the C variable may not match (e.g., Intel 9.0 compilers on 64 bit 50 * platforms will put the alignment of a double on 4 bytes, but put 51 * the alignment of all common blocks on 16 bytes). This only matters 52 * (to some compilers!), however, if you initialize the C variable in 53 * the global scope. If the C global instantiation is not 54 * initialized, the compiler/linker seems to "figure it all out" and 55 * make the alignments match. 56 * 57 * Since we made the fundamental decision to support all 4 common 58 * fortran compiler symbol conventions within the same library for 59 * those compilers who support weak symbols, we need to have 4 symbols 60 * for each of the fortran address constants. As described above, we 61 * have to have known *pointer* values for the fortran addresses 62 * (e.g., MPI_STATUS_IGNORE). So when the fortran wrapper for 63 * MPI_RECV gets (MPI_Fint *status), it can check (status == 64 * some_sentinel_value) to know that it got the Fortran equivalent of 65 * MPI_STATUS_IGNORE and therefore pass the C MPI_STATUS_IGNORE to the 66 * C MPI_Recv. 67 * 68 * We do this by having a "common" block in mpif.h: 69 * 70 * INTEGER MPI_STATUS_IGNORE(MPI_STATUS_SIZE) 71 * common /mpi_fortran_status_ignore/ MPI_STATUS_IGNORE 72 * 73 * This makes the fortran variable MPI_STATUS_IGNORE effectively be an 74 * alias for the C variable "mpi_fortran_status_ignore" -- but the C 75 * symbol name is according to the fortran compiler's naming symbol 76 * convention bais. So it could be MPI_FORTRAN_STATUS_IGNORE, 77 * mpi_fortran_status_ignore, mpi_fortran_status_ignore_, or 78 * mpi_fortran_status_ignore__. 79 * 80 * Hence, we have to have *4* C symbols for this, and them compare for 81 * all of them in the fortran MPI_RECV wrapper. :-( I can't think of 82 * any better way to do this. 83 * 84 * I'm putting these 4 comparisons in macros (on systems where we 85 * don't support the 4 symbols -- e.g., OSX, where we don't have weak 86 * symbols -- it'll only be one comparison), so if anyone things of 87 * something better than this, you should only need to modify this 88 * file. 89 */ 90 91 #include "mpif-c-constants-decl.h" 92 93 /* Convert between Fortran and C MPI_BOTTOM */ 94 #define OMPI_F2C_BOTTOM(addr) (OMPI_IS_FORTRAN_BOTTOM(addr) ? MPI_BOTTOM : (addr)) 95 #define OMPI_F2C_IN_PLACE(addr) (OMPI_IS_FORTRAN_IN_PLACE(addr) ? MPI_IN_PLACE : (addr)) 96 #define OMPI_F2C_UNWEIGHTED(addr) (OMPI_IS_FORTRAN_UNWEIGHTED(addr) ? MPI_UNWEIGHTED : (addr)) 97 #define OMPI_F2C_WEIGHTS_EMPTY(addr) (OMPI_IS_FORTRAN_WEIGHTS_EMPTY(addr) ? MPI_WEIGHTS_EMPTY : (addr)) 98 99 #endif /* OMPI_BUILD_FORTRAN_BINDINGS */ 100 101 #endif /* OMPI_FORTRAN_BASE_CONSTANTS_H */