Blame test/mpi/f90/attr/attrlangc.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *
Packit Service c5cf8c
 *  (C) 2012 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include "mpi.h"
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
#include "../../include/mpitestconf.h"
Packit Service c5cf8c
Packit Service c5cf8c
/* Used to convert Fortran strings (which may not be null terminated) to
Packit Service c5cf8c
   C strings */
Packit Service c5cf8c
#define MAX_ATTRTEST_MSG 256
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
 * FIXME: This code assumes that character strings are passed from Fortran
Packit Service c5cf8c
 * by placing the string length, as an int, at the end of the argument list
Packit Service c5cf8c
 * This is common but not universal.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
   Name mapping.  All routines are created with names that are lower case
Packit Service c5cf8c
   with a single trailing underscore.  This matches many compilers.
Packit Service c5cf8c
   We use #define to change the name for Fortran compilers that do
Packit Service c5cf8c
   not use the lowercase/underscore pattern
Packit Service c5cf8c
*/
Packit Service c5cf8c
Packit Service c5cf8c
#ifdef F77_NAME_UPPER
Packit Service c5cf8c
#define cattrinit_   CATTRINIT
Packit Service c5cf8c
#define cgetenvbool_ CGETENVBOOL
Packit Service c5cf8c
#define cgetsizes_   CGETSIZES
Packit Service c5cf8c
#define ccreatekeys_ CCREATEKEYS
Packit Service c5cf8c
#define cfreekeys_   CFREEKEYS
Packit Service c5cf8c
#define ctoctest_    CTOCTEST
Packit Service c5cf8c
#define cmpif1read_  CMPIF1READ
Packit Service c5cf8c
#define cmpif2read_  CMPIF2READ
Packit Service c5cf8c
#define cmpif2readtype_  CMPIF2READTYPE
Packit Service c5cf8c
#define cmpif2readwin_   CMPIF2READWIN
Packit Service c5cf8c
#define csetmpi_     CSETMPI
Packit Service c5cf8c
#define csetmpi2_    CSETMPI2
Packit Service c5cf8c
#define csetmpitype_ CSETMPITYPE
Packit Service c5cf8c
#define csetmpiwin_  CSETMPIWIN
Packit Service c5cf8c
Packit Service c5cf8c
#elif defined(F77_NAME_LOWER) || defined(F77_NAME_MIXED)
Packit Service c5cf8c
/* Mixed is ok because we use lowercase in all uses */
Packit Service c5cf8c
#define cattrinit_   cattrinit
Packit Service c5cf8c
#define cgetenvbool_ cgetenvbool
Packit Service c5cf8c
#define cgetsizes_   cgetsizes
Packit Service c5cf8c
#define ccreatekeys_ ccreatekeys
Packit Service c5cf8c
#define cfreekeys_   cfreekeys
Packit Service c5cf8c
#define ctoctest_    ctoctest
Packit Service c5cf8c
#define cmpif1read_  cmpif1read
Packit Service c5cf8c
#define cmpif2read_  cmpif2read
Packit Service c5cf8c
#define cmpif2readtype_  cmpif2readtype
Packit Service c5cf8c
#define cmpif2readwin_   cmpif2readwin
Packit Service c5cf8c
#define csetmpi_     csetmpi
Packit Service c5cf8c
#define csetmpi2_    csetmpi2
Packit Service c5cf8c
#define csetmpitype_ csetmpitype
Packit Service c5cf8c
#define csetmpiwin_  csetmpiwin
Packit Service c5cf8c
Packit Service c5cf8c
#elif defined(F77_NAME_LOWER_2USCORE) || defined(F77_NAME_LOWER_USCORE) || \
Packit Service c5cf8c
      defined(F77_NAME_MIXED_USCORE)
Packit Service c5cf8c
/* Else leave name alone (routines have no underscore, so both
Packit Service c5cf8c
   of these map to a lowercase, single underscore) */
Packit Service c5cf8c
#else
Packit Service c5cf8c
#error 'Unrecognized Fortran name mapping'
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
/* */
Packit Service c5cf8c
static int ccomm1Key, ccomm2Key, ctype2Key, cwin2Key;
Packit Service c5cf8c
static int ccomm1Extra, ccomm2Extra, ctype2Extra, cwin2Extra;
Packit Service c5cf8c
static int verbose = 0;
Packit Service c5cf8c
Packit Service c5cf8c
/* Forward references */
Packit Service c5cf8c
int cmpi1read(MPI_Comm comm, int key, void *expected, const char *msg);
Packit Service c5cf8c
int cmpi2read(MPI_Comm comm, int key, void *expected, const char *msg);
Packit Service c5cf8c
int cmpi2readtype(MPI_Datatype dtype, int key, void *expected, const char *msg);
Packit Service c5cf8c
Packit Service c5cf8c
void ccompareint2aint_(MPI_Fint * in1, MPI_Aint * in2, MPI_Fint * result);
Packit Service c5cf8c
void ccompareint2void_(MPI_Fint * in1, void *in2, MPI_Fint * result);
Packit Service c5cf8c
void ccompareaint2void_(MPI_Aint * in1, void *in2, MPI_Fint * result);
Packit Service c5cf8c
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
/* Initialization functions                                                */
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
void cgetenvbool_(const char str[], MPI_Fint * val, int d)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *envval;
Packit Service c5cf8c
    char envname[1024];
Packit Service c5cf8c
    /* Note that the Fortran string may not be null terminated; thus
Packit Service c5cf8c
     * we copy d characters and add a null just in case */
Packit Service c5cf8c
    if (d > sizeof(envname) - 1) {
Packit Service c5cf8c
        fprintf(stderr, "Environment variable name too long (%d)\n", d);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    strncpy(envname, str, d);
Packit Service c5cf8c
    envname[d] = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    envval = getenv(envname);
Packit Service c5cf8c
    *val = 0;
Packit Service c5cf8c
    if (envval) {
Packit Service c5cf8c
        printf(" envval = %s\n", envval);
Packit Service c5cf8c
        if (strcmp(envval, "yes") == 0 || strcmp(envval, "YES") == 0 ||
Packit Service c5cf8c
            strcmp(envval, "true") == 0 || strcmp(envval, "TRUE") == 0)
Packit Service c5cf8c
            *val = 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Keep our own copy of the "is verbose" state */
Packit Service c5cf8c
void cattrinit_(MPI_Fint * fverbose)
Packit Service c5cf8c
{
Packit Service c5cf8c
    verbose = (int) *fverbose;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Provide attribute sizes (C, Fortran 1, Fortran 2) */
Packit Service c5cf8c
void cgetsizes_(MPI_Fint * ptrSize, MPI_Fint * intSize, MPI_Fint * aintSize)
Packit Service c5cf8c
{
Packit Service c5cf8c
    *ptrSize = (MPI_Fint) sizeof(void *);
Packit Service c5cf8c
    *intSize = (MPI_Fint) sizeof(MPI_Fint);
Packit Service c5cf8c
    *aintSize = (MPI_Fint) sizeof(MPI_Aint);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
/* Copy and delete functions attached to keyvals                           */
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
static int CMPI1_COPY_FN(MPI_Comm comm, int keyval, void *extra,
Packit Service c5cf8c
                         void *inval, void *outval, int *flag)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int inValue = *(int *) inval;
Packit Service c5cf8c
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf(" In C MPI-1 copy function: inval = %p, extra = %p\n", inval, extra);
Packit Service c5cf8c
    *flag = 1;
Packit Service c5cf8c
    /* We don't change the attribute */
Packit Service c5cf8c
    *(void **) outval = inval;
Packit Service c5cf8c
    /* But we do change what it points at */
Packit Service c5cf8c
    *(int *) inval = inValue + 1;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static int CMPI1_DELETE_FN(MPI_Comm comm, int keyval, void *outval, void *extra)
Packit Service c5cf8c
{
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf(" In C MPI-1 delete function, extra = %p\n", extra);
Packit Service c5cf8c
    *(int *) outval = *(int *) outval - 1;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static int TYPE_COPY_FN(MPI_Datatype dtype, int keyval, void *extra,
Packit Service c5cf8c
                        void *inval, void *outval, int *flag)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int inValue = *(int *) inval;
Packit Service c5cf8c
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf(" In C MPI type copy function, inval = %p, extra = %p\n", inval, extra);
Packit Service c5cf8c
    *flag = 1;
Packit Service c5cf8c
    /* We don't change the attribute */
Packit Service c5cf8c
    *(void **) outval = inval;
Packit Service c5cf8c
    /* But we do change what it points at */
Packit Service c5cf8c
    *(int *) inval = inValue + 1;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static int TYPE_DELETE_FN(MPI_Datatype dtype, int keyval, void *outval, void *extra)
Packit Service c5cf8c
{
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf(" In C MPI type delete function, extra = %p\n", extra);
Packit Service c5cf8c
    /* We reverse the incrment used in copy (checked after free of the type) */
Packit Service c5cf8c
    *(int *) outval = *(int *) outval - 1;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Note that this function cannot be called in MPI since there is no
Packit Service c5cf8c
   win_dup function */
Packit Service c5cf8c
static int WIN_COPY_FN(MPI_Win win, int keyval, void *extra, void *inval, void *outval, int *flag)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int inValue = *(int *) inval;
Packit Service c5cf8c
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf("PANIC: In C MPI win copy function (should never happen)\n");
Packit Service c5cf8c
    *flag = 1;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
static int WIN_DELETE_FN(MPI_Win win, int keyval, void *outval, void *extra)
Packit Service c5cf8c
{
Packit Service c5cf8c
    if (verbose)
Packit Service c5cf8c
        printf(" In C MPI win delete function, extra = %p\n", extra);
Packit Service c5cf8c
    *(int *) outval = *(int *) outval - 1;
Packit Service c5cf8c
    return MPI_SUCCESS;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
/* Routines to create keyvals in C (with C copy and delete functions       */
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
Packit Service c5cf8c
void ccreatekeys_(MPI_Fint * ccomm1_key, MPI_Fint * ccomm2_key,
Packit Service c5cf8c
                  MPI_Fint * ctype2_key, MPI_Fint * cwin2_key)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Keyval_create(CMPI1_COPY_FN, CMPI1_DELETE_FN, &ccomm1Key, &ccomm1Extra);
Packit Service c5cf8c
    *ccomm1_key = (MPI_Fint) ccomm1Key;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_create_keyval(CMPI1_COPY_FN, CMPI1_DELETE_FN, &ccomm2Key, &ccomm2Extra);
Packit Service c5cf8c
    *ccomm2_key = (MPI_Fint) ccomm2Key;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Type_create_keyval(TYPE_COPY_FN, TYPE_DELETE_FN, &ctype2Key, &ctype2Extra);
Packit Service c5cf8c
    *ctype2_key = (MPI_Fint) ctype2Key;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Win_create_keyval(WIN_COPY_FN, WIN_DELETE_FN, &cwin2Key, &cwin2Extra);
Packit Service c5cf8c
    *cwin2_key = (MPI_Fint) cwin2Key;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void cfreekeys_(void)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Keyval_free(&ccomm1Key);
Packit Service c5cf8c
    MPI_Comm_free_keyval(&ccomm2Key);
Packit Service c5cf8c
    MPI_Type_free_keyval(&ctype2Key);
Packit Service c5cf8c
    MPI_Win_free_keyval(&cwin2Key);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
Packit Service c5cf8c
/* Test c-to-c attributes */
Packit Service c5cf8c
static int ccomm1Attr, ccomm2Attr, ctype2Attr, cwin2Attr;
Packit Service c5cf8c
Packit Service c5cf8c
void ctoctest_(MPI_Fint * errs)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int errcnt = *errs;
Packit Service c5cf8c
    int baseattrval = (1 << (sizeof(int) * 8 - 2)) - 3;
Packit Service c5cf8c
    MPI_Datatype cduptype;
Packit Service c5cf8c
    MPI_Comm cdup;
Packit Service c5cf8c
Packit Service c5cf8c
    /* MPI-1 function */
Packit Service c5cf8c
    ccomm1Attr = baseattrval;
Packit Service c5cf8c
    MPI_Attr_put(MPI_COMM_SELF, ccomm1Key, &ccomm1Attr);
Packit Service c5cf8c
    /* Test that we have the same value */
Packit Service c5cf8c
    errcnt += cmpi1read(MPI_COMM_SELF, ccomm1Key, &ccomm1Attr, "C to C");
Packit Service c5cf8c
Packit Service c5cf8c
    /* Dup, check that the copy routine does what is expected */
Packit Service c5cf8c
    MPI_Comm_dup(MPI_COMM_SELF, &cdup);
Packit Service c5cf8c
    errcnt += cmpi1read(cdup, ccomm1Key, &ccomm1Attr, "C to C dup");
Packit Service c5cf8c
    if (ccomm1Attr != baseattrval + 1) {
Packit Service c5cf8c
        printf(" Did not increment int in C to C dup: %d %d\n", ccomm1Attr, baseattrval + 1);
Packit Service c5cf8c
        errcnt++;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_free(&cdup);
Packit Service c5cf8c
    if (ccomm1Attr != baseattrval) {
Packit Service c5cf8c
        printf(" Did not increment int in C to C delete: %d %d\n", ccomm1Attr, baseattrval);
Packit Service c5cf8c
        errcnt++;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* MPI-2 functions */
Packit Service c5cf8c
    ccomm1Attr = 0;
Packit Service c5cf8c
    ccomm2Attr = baseattrval;
Packit Service c5cf8c
    MPI_Comm_set_attr(MPI_COMM_SELF, ccomm2Key, &ccomm2Attr);
Packit Service c5cf8c
    /* Test that we have the same value */
Packit Service c5cf8c
    errcnt += cmpi2read(MPI_COMM_SELF, ccomm2Key, &ccomm2Attr, "C to C (2)");
Packit Service c5cf8c
Packit Service c5cf8c
    /* Dup, check that the copy routine does what is expected */
Packit Service c5cf8c
    MPI_Comm_dup(MPI_COMM_SELF, &cdup);
Packit Service c5cf8c
    errcnt += cmpi2read(cdup, ccomm2Key, &ccomm2Attr, "C to C dup (2)");
Packit Service c5cf8c
    if (ccomm2Attr != baseattrval + 1) {
Packit Service c5cf8c
        printf(" Did not increment int in C to C dup: %d %d\n", ccomm2Attr, baseattrval + 1);
Packit Service c5cf8c
        errcnt++;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_free(&cdup);
Packit Service c5cf8c
    if (ccomm2Attr != baseattrval) {
Packit Service c5cf8c
        printf(" Did not increment int in C to C delete (2): %d %d\n", ccomm2Attr, baseattrval);
Packit Service c5cf8c
        errcnt++;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    /* MPI-2 functions */
Packit Service c5cf8c
    ctype2Attr = baseattrval;
Packit Service c5cf8c
    MPI_Type_set_attr(MPI_INTEGER, ctype2Key, &ctype2Attr);
Packit Service c5cf8c
    /* Test that we have the same value */
Packit Service c5cf8c
    errcnt += cmpi2readtype(MPI_INTEGER, ctype2Key, &ctype2Attr, "C to C type (2)");
Packit Service c5cf8c
Packit Service c5cf8c
    /* Dup, check that the copy routine does what is expected */
Packit Service c5cf8c
    MPI_Type_dup(MPI_INTEGER, &cduptype);
Packit Service c5cf8c
    errcnt += cmpi2readtype(cduptype, ctype2Key, &ctype2Attr, "C to C typedup (2)");
Packit Service c5cf8c
    if (ctype2Attr != baseattrval + 1) {
Packit Service c5cf8c
        printf(" Did not increment int in C to C typedup: %d %d\n", ctype2Attr, baseattrval + 1);
Packit Service c5cf8c
        errcnt++;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    ccomm1Attr = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Type_free(&cduptype);
Packit Service c5cf8c
    if (ctype2Attr != baseattrval) {
Packit Service c5cf8c
        printf(" Did not increment int in C to C typedelete (2): %d %d\n", ctype2Attr, baseattrval);
Packit Service c5cf8c
        errcnt++;
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
    *errs = errcnt;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
/* Routines to get and check an attribute value.  Returns the number       */
Packit Service c5cf8c
/*   of errors found                                                       */
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
Packit Service c5cf8c
int cmpi1read(MPI_Comm comm, int key, void *expected, const char *msg)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag;
Packit Service c5cf8c
    MPI_Attr_get(comm, key, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        printf(" Error: flag false for Attr_get: %s\n", msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (attrval != expected) {
Packit Service c5cf8c
        printf(" Error: expected %p but saw %p: %s\n", expected, attrval, msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
int cmpi2read(MPI_Comm comm, int key, void *expected, const char *msg)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag;
Packit Service c5cf8c
    MPI_Comm_get_attr(comm, key, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        printf(" Error: flag false for Comm_get_attr: %s\n", msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (attrval != expected) {
Packit Service c5cf8c
        printf(" Error: expected %p but saw %p: %s\n", expected, attrval, msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
int cmpi2readtype(MPI_Datatype dtype, int key, void *expected, const char *msg)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag;
Packit Service c5cf8c
    MPI_Type_get_attr(dtype, key, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        printf(" Error: flag false for Type_get_attr: %s\n", msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (attrval != expected) {
Packit Service c5cf8c
        printf(" Error: expected %p but saw %p: %s\n", expected, attrval, msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
int cmpi2readwin(MPI_Win win, int key, void *expected, const char *msg)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag;
Packit Service c5cf8c
    MPI_Win_get_attr(win, key, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        printf(" Error: flag false for Win_get_attr: %s\n", msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (attrval != expected) {
Packit Service c5cf8c
        printf(" Error: expected %p but saw %p: %s\n", expected, attrval, msg);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Set in Fortran (MPI-1), read in C */
Packit Service c5cf8c
void cmpif1read_(MPI_Fint * fcomm, MPI_Fint * fkey, MPI_Fint * expected,
Packit Service c5cf8c
                 MPI_Fint * errs, const char *msg, int msglen)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag, result;
Packit Service c5cf8c
    MPI_Comm comm = MPI_Comm_f2c(*fcomm);
Packit Service c5cf8c
    char lmsg[MAX_ATTRTEST_MSG];
Packit Service c5cf8c
Packit Service c5cf8c
    if (msglen > sizeof(lmsg) - 1) {
Packit Service c5cf8c
        fprintf(stderr, "Message too long for buffer (%d)\n", msglen);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Attr_get(comm, *fkey, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: flag false for Attr_get (set in F1): %s\n", lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    /* Must be careful to compare as required in the MPI specification */
Packit Service c5cf8c
    ccompareint2void_(expected, attrval, &result);
Packit Service c5cf8c
    if (!result) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: (set in F1) expected %d but saw %d: %s\n",
Packit Service c5cf8c
               *expected, *(MPI_Fint *) attrval, lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Set in Fortran (MPI-2), read in C */
Packit Service c5cf8c
void cmpif2read_(MPI_Fint * fcomm, MPI_Fint * fkey, MPI_Aint * expected,
Packit Service c5cf8c
                 MPI_Fint * errs, const char *msg, int msglen)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag, result;
Packit Service c5cf8c
    MPI_Comm comm = MPI_Comm_f2c(*fcomm);
Packit Service c5cf8c
    char lmsg[MAX_ATTRTEST_MSG];
Packit Service c5cf8c
Packit Service c5cf8c
    if (msglen > sizeof(lmsg) - 1) {
Packit Service c5cf8c
        fprintf(stderr, "Message too long for buffer (%d)\n", msglen);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_get_attr(comm, *fkey, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: flag false for Comm_get_attr (set in F2): %s\n", lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    ccompareaint2void_(expected, attrval, &result);
Packit Service c5cf8c
    if (!result) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: (set in F2) expected %ld but saw %ld: %s\n",
Packit Service c5cf8c
               (long) *expected, (long) *(MPI_Aint *) attrval, lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void cmpif2readtype_(MPI_Fint * ftype, MPI_Fint * fkey, MPI_Aint * expected,
Packit Service c5cf8c
                     MPI_Fint * errs, const char *msg, int msglen)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag, result;
Packit Service c5cf8c
    MPI_Datatype dtype = MPI_Type_f2c(*ftype);
Packit Service c5cf8c
    char lmsg[MAX_ATTRTEST_MSG];
Packit Service c5cf8c
Packit Service c5cf8c
    if (msglen > sizeof(lmsg) - 1) {
Packit Service c5cf8c
        fprintf(stderr, "Message too long for buffer (%d)\n", msglen);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Type_get_attr(dtype, *fkey, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: flag false for Type_get_attr (set in F2): %s\n", lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    ccompareaint2void_(expected, attrval, &result);
Packit Service c5cf8c
    if (!result) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: (set in F2/Type) expected %ld but saw %ld: %s\n",
Packit Service c5cf8c
               (long) *expected, (long) *(MPI_Aint *) attrval, lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void cmpif2readwin_(MPI_Fint * fwin, MPI_Fint * fkey, MPI_Aint * expected,
Packit Service c5cf8c
                    MPI_Fint * errs, const char *msg, int msglen)
Packit Service c5cf8c
{
Packit Service c5cf8c
    void *attrval;
Packit Service c5cf8c
    int flag, result;
Packit Service c5cf8c
    MPI_Win win = MPI_Win_f2c(*fwin);
Packit Service c5cf8c
    char lmsg[MAX_ATTRTEST_MSG];
Packit Service c5cf8c
Packit Service c5cf8c
    if (msglen > sizeof(lmsg) - 1) {
Packit Service c5cf8c
        fprintf(stderr, "Message too long for buffer (%d)\n", msglen);
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Win_get_attr(win, *fkey, &attrval, &flag;;
Packit Service c5cf8c
    if (!flag) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: flag false for Win_get_attr (set in F2): %s\n", lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    ccompareaint2void_(expected, attrval, &result);
Packit Service c5cf8c
    if (!result) {
Packit Service c5cf8c
        *errs = *errs + 1;
Packit Service c5cf8c
        strncpy(lmsg, msg, msglen);
Packit Service c5cf8c
        lmsg[msglen] = 0;
Packit Service c5cf8c
        printf(" Error: (set in F2/Win) expected %ld but saw %ld: %s\n",
Packit Service c5cf8c
               (long) *expected, (long) *(MPI_Aint *) attrval, lmsg);
Packit Service c5cf8c
        return;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
/* Given a Fortran attribute (pointer to the value to store), set it using */
Packit Service c5cf8c
/* the C attribute functions                                               */
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
Packit Service c5cf8c
void csetmpi_(MPI_Fint * fcomm, MPI_Fint * fkey, MPI_Fint * val, MPI_Fint * errs)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Comm comm = MPI_Comm_f2c(*fcomm);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_set_attr(comm, *fkey, (void *) (MPI_Aint) * val);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void csetmpi2_(MPI_Fint * fcomm, MPI_Fint * fkey, MPI_Aint * val, MPI_Fint * errs)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Comm comm = MPI_Comm_f2c(*fcomm);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_set_attr(comm, *fkey, (void *) *val);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void csetmpitype_(MPI_Fint * ftype, MPI_Fint * fkey, MPI_Aint * val, MPI_Fint * errs)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Datatype dtype = MPI_Type_f2c(*ftype);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Type_set_attr(dtype, *fkey, (void *) *val);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void csetmpiwin_(MPI_Fint * fwin, MPI_Fint * fkey, MPI_Aint * val, MPI_Fint * errs)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI_Win win = MPI_Win_f2c(*fwin);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Win_set_attr(win, *fkey, (void *) *val);
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
/* Comparisons                                                             */
Packit Service c5cf8c
/*    int with aint                                                        */
Packit Service c5cf8c
/*    int with void*                                                       */
Packit Service c5cf8c
/*    aint with void*                                                      */
Packit Service c5cf8c
/* All routines use similar interfaces, though the routines that involve   */
Packit Service c5cf8c
/* void * must be called from C                                            */
Packit Service c5cf8c
/* Defined to be callable from either C or Fortran                         */
Packit Service c5cf8c
/* Here is the rule, defined in the MPI standard:                          */
Packit Service c5cf8c
/*    If one item is shorter than the other, take the low bytes.           */
Packit Service c5cf8c
/*    If one item is longer than the other, sign extend                    */
Packit Service c5cf8c
/* ----------------------------------------------------------------------- */
Packit Service c5cf8c
void ccompareint2aint_(MPI_Fint * in1, MPI_Aint * in2, MPI_Fint * result)
Packit Service c5cf8c
{
Packit Service c5cf8c
    static int idx = -1;
Packit Service c5cf8c
    if (sizeof(MPI_Fint) == sizeof(MPI_Aint)) {
Packit Service c5cf8c
        *result = *in1 == *in2;
Packit Service c5cf8c
    } else if (sizeof(MPI_Fint) < sizeof(MPI_Aint)) {
Packit Service c5cf8c
        /* Assume Aint no smaller than Fint, and that size of aint
Packit Service c5cf8c
         * is a multiple of the size of fint) */
Packit Service c5cf8c
        MPI_Fint *v2 = (MPI_Fint *) in2;
Packit Service c5cf8c
        if (idx < 0) {
Packit Service c5cf8c
            MPI_Aint av = 1;
Packit Service c5cf8c
            MPI_Fint *fa = (MPI_Fint *) & av;
Packit Service c5cf8c
            if ((sizeof(MPI_Aint) % sizeof(MPI_Fint)) != 0) {
Packit Service c5cf8c
                fprintf(stderr,
Packit Service c5cf8c
                        "PANIC: size of MPI_Aint = %d not a multiple of MPI_Fint = %d\n",
Packit Service c5cf8c
                        (int) sizeof(MPI_Aint), (int) sizeof(MPI_Fint));
Packit Service c5cf8c
                MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            for (idx = sizeof(MPI_Aint) / sizeof(MPI_Fint); idx >= 0; idx--)
Packit Service c5cf8c
                if (fa[idx])
Packit Service c5cf8c
                    break;
Packit Service c5cf8c
            if (idx < 0) {
Packit Service c5cf8c
                fprintf(stderr, "Unable to determine low word of Fint in Aint\n");
Packit Service c5cf8c
                MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            *result = *in1 == v2[idx];
Packit Service c5cf8c
        }
Packit Service c5cf8c
    } else {
Packit Service c5cf8c
        fprintf(stderr, "PANIC: sizeof(MPI_Fint) = %d > sizeof(MPI_Aint) %d\n",
Packit Service c5cf8c
                (int) sizeof(MPI_Fint), (int) sizeof(MPI_Aint));
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void ccompareint2void_(MPI_Fint * in1, void *in2, MPI_Fint * result)
Packit Service c5cf8c
{
Packit Service c5cf8c
    static int idx = -1;
Packit Service c5cf8c
    if (sizeof(MPI_Fint) == sizeof(void *)) {
Packit Service c5cf8c
        *result = *in1 == *(MPI_Fint *) in2;
Packit Service c5cf8c
    } else if (sizeof(MPI_Fint) < sizeof(void *)) {
Packit Service c5cf8c
        /* Assume void* no smaller than Fint, and that size of aint
Packit Service c5cf8c
         * is a multiple of the size of fint) */
Packit Service c5cf8c
        MPI_Fint *v2 = (MPI_Fint *) in2;
Packit Service c5cf8c
        if (idx < 0) {
Packit Service c5cf8c
            void *av = (void *) 1;
Packit Service c5cf8c
            MPI_Fint *fa = (MPI_Fint *) & av;
Packit Service c5cf8c
            if ((sizeof(void *) % sizeof(MPI_Fint)) != 0) {
Packit Service c5cf8c
                fprintf(stderr,
Packit Service c5cf8c
                        "PANIC: size of void * = %d not a multiple of MPI_Fint = %d\n",
Packit Service c5cf8c
                        (int) sizeof(void *), (int) sizeof(MPI_Fint));
Packit Service c5cf8c
                MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            for (idx = sizeof(void *) / sizeof(MPI_Fint); idx >= 0; idx--)
Packit Service c5cf8c
                if (fa[idx])
Packit Service c5cf8c
                    break;
Packit Service c5cf8c
            if (idx < 0) {
Packit Service c5cf8c
                fprintf(stderr, "Unable to determine low word of Fint in void*\n");
Packit Service c5cf8c
                MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            *result = *in1 == v2[idx];
Packit Service c5cf8c
        }
Packit Service c5cf8c
    } else {
Packit Service c5cf8c
        fprintf(stderr, "PANIC: sizeof(MPI_Fint) = %d > sizeof(void*) %d\n",
Packit Service c5cf8c
                (int) sizeof(MPI_Fint), (int) sizeof(void *));
Packit Service c5cf8c
        MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
void ccompareaint2void_(MPI_Aint * in1, void *in2, MPI_Fint * result)
Packit Service c5cf8c
{
Packit Service c5cf8c
    /* Note that an aint must be >= void * by definition */
Packit Service c5cf8c
    *result = *in1 == *(MPI_Aint *) in2;
Packit Service c5cf8c
}