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