Blame test/mpi/mpi_t/mpi_t_str.c

Packit 0848f5
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit 0848f5
/*
Packit 0848f5
 *  (C) 2012 by Argonne National Laboratory.
Packit 0848f5
 *      See COPYRIGHT in top-level directory.
Packit 0848f5
 */
Packit 0848f5
Packit 0848f5
/* A test that MPI_T string handling is working as expected.  Necessarily a weak
Packit 0848f5
 * test, since we can't assume any particular variables are exposed by the
Packit 0848f5
 * implementation. */
Packit 0848f5
Packit 0848f5
#include "mpi.h"
Packit 0848f5
#include <stdlib.h>
Packit 0848f5
#include <stdio.h>
Packit 0848f5
#include <string.h>
Packit 0848f5
#include <assert.h>
Packit 0848f5
#include <math.h>
Packit 0848f5
#include <limits.h>
Packit 0848f5
#include "mpitestconf.h"
Packit 0848f5
Packit 0848f5
/* assert-like macro that bumps the err count and emits a message */
Packit 0848f5
#define check(x_)                                                                 \
Packit 0848f5
    do {                                                                          \
Packit 0848f5
        if (!(x_)) {                                                              \
Packit 0848f5
            ++errs;                                                               \
Packit 0848f5
            if (errs < 10) {                                                      \
Packit 0848f5
                fprintf(stderr, "check failed: (%s), line %d\n", #x_, __LINE__); \
Packit 0848f5
            }                                                                     \
Packit 0848f5
        }                                                                         \
Packit 0848f5
    } while (0)
Packit 0848f5
Packit 0848f5
/* the usual multiple-evaluation caveats apply to this routine */
Packit 0848f5
#define min(a,b) ((a) < (b) ? (a) : (b))
Packit 0848f5
Packit 0848f5
int main(int argc, char **argv)
Packit 0848f5
{
Packit 0848f5
    int errs = 0;
Packit 0848f5
    int i, j;
Packit 0848f5
    int rank, size;
Packit 0848f5
    int num_pvars, num_cvars, num_cat;
Packit 0848f5
#define STR_SZ (50)
Packit 0848f5
    int name_len;
Packit 0848f5
    char name[STR_SZ + 1] = ""; /* +1 to check for overrun */
Packit 0848f5
    int desc_len;
Packit 0848f5
    char desc[STR_SZ + 1] = ""; /* +1 to check for overrun */
Packit 0848f5
    int verb;
Packit 0848f5
    MPI_Datatype dtype;
Packit 0848f5
    int count;
Packit 0848f5
    int bind;
Packit 0848f5
    int scope;
Packit 0848f5
    int provided;
Packit 0848f5
Packit 0848f5
    /* Init'ed to a garbage value, to trigger MPI_T bugs easily if there are. */
Packit 0848f5
    MPI_T_enum enumtype = (MPI_T_enum) 0x31415926;
Packit 0848f5
Packit 0848f5
    MPI_Init(&argc, &argv);
Packit 0848f5
    MPI_T_init_thread(MPI_THREAD_SINGLE, &provided);
Packit 0848f5
Packit 0848f5
    MPI_Comm_rank(MPI_COMM_WORLD, &rank;;
Packit 0848f5
    MPI_Comm_size(MPI_COMM_WORLD, &size);
Packit 0848f5
Packit 0848f5
    /* loop over all cvars and ask for string arguments with various valid
Packit 0848f5
     * combinations of NULL and non-NULL to ensure that the library handles this
Packit 0848f5
     * case correctly */
Packit 0848f5
    MPI_T_cvar_get_num(&num_cvars);
Packit 0848f5
    for (i = 0; i < num_cvars; ++i) {
Packit 0848f5
        int full_name_len, full_desc_len;
Packit 0848f5
        /* pass NULL string, non-zero lengths; should get full lengths */
Packit 0848f5
        full_name_len = full_desc_len = 1;
Packit 0848f5
        MPI_T_cvar_get_info(i, NULL, &full_name_len, &verb, &dtype,
Packit 0848f5
                            &enumtype, NULL, &full_desc_len, &bind, &scope);
Packit 0848f5
        check(full_name_len >= 0);
Packit 0848f5
        check(full_desc_len >= 0);
Packit 0848f5
Packit 0848f5
        /* pass non-NULL string, zero lengths; should get full lengths also */
Packit 0848f5
        name_len = desc_len = 0;
Packit 0848f5
        MPI_T_cvar_get_info(i, name, &name_len, &verb, &dtype,
Packit 0848f5
                            &enumtype, desc, &desc_len, &bind, &scope);
Packit 0848f5
        check(full_name_len == name_len);
Packit 0848f5
        check(full_desc_len == desc_len);
Packit 0848f5
Packit 0848f5
        /* regular call, no NULLs; should truncate (with termination) to STR_SZ
Packit 0848f5
         * if necessary, otherwise returns strlen+1 in the corresponding "_len"
Packit 0848f5
         * var */
Packit 0848f5
        name_len = desc_len = STR_SZ;
Packit 0848f5
        MPI_T_cvar_get_info(i, name, &name_len, &verb, &dtype,
Packit 0848f5
                            &enumtype, desc, &desc_len, &bind, &scope);
Packit 0848f5
        check((strlen(name) + 1) == min(name_len, STR_SZ));
Packit 0848f5
        check((strlen(desc) + 1) == min(desc_len, STR_SZ));
Packit 0848f5
Packit 0848f5
        /* pass NULL lengths, string buffers should be left alone */
Packit 0848f5
        for (j = 0; j < STR_SZ; ++j) {
Packit 0848f5
            name[j] = j % CHAR_MAX;
Packit 0848f5
            desc[j] = j % CHAR_MAX;
Packit 0848f5
        }
Packit 0848f5
        MPI_T_cvar_get_info(i, name, /*name_len= */ NULL, &verb, &dtype,
Packit 0848f5
                            &enumtype, desc, /*desc_len= */ NULL, &bind, &scope);
Packit 0848f5
        for (j = 0; j < STR_SZ; ++j) {
Packit 0848f5
            check(name[j] == j % CHAR_MAX);
Packit 0848f5
            check(desc[j] == j % CHAR_MAX);
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        /* not much of a string test, just need a quick spot to stick a test for
Packit 0848f5
         * the existence of the correct MPI_T prototype (tt#1727) */
Packit 0848f5
        /* Include test that enumtype is defined */
Packit 0848f5
        if (dtype == MPI_INT && enumtype != MPI_T_ENUM_NULL) {
Packit 0848f5
            int num_enumtype = -1;
Packit 0848f5
            name_len = STR_SZ;
Packit 0848f5
            MPI_T_enum_get_info(enumtype, &num_enumtype, name, &name_len);
Packit 0848f5
            check(num_enumtype >= 0);
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    /* check string handling for performance variables */
Packit 0848f5
    MPI_T_pvar_get_num(&num_pvars);
Packit 0848f5
    for (i = 0; i < num_pvars; ++i) {
Packit 0848f5
        int varclass, bind, readonly, continuous, atomic;
Packit 0848f5
        MPI_Datatype dtype;
Packit 0848f5
        MPI_T_enum enumtype;
Packit 0848f5
Packit 0848f5
        int full_name_len, full_desc_len;
Packit 0848f5
        /* pass NULL string, non-zero lengths; should get full lengths */
Packit 0848f5
        full_name_len = full_desc_len = 1;
Packit 0848f5
        MPI_T_pvar_get_info(i, NULL, &full_name_len, &verb, &varclass, &dtype,
Packit 0848f5
                            &enumtype, NULL, &full_desc_len, &bind, &readonly,
Packit 0848f5
                            &continuous, &atomic);
Packit 0848f5
        check(full_name_len >= 0);
Packit 0848f5
        check(full_desc_len >= 0);
Packit 0848f5
Packit 0848f5
        /* pass non-NULL string, zero lengths; should get full lengths also */
Packit 0848f5
        name_len = desc_len = 0;
Packit 0848f5
        MPI_T_pvar_get_info(i, name, &name_len, &verb, &varclass, &dtype,
Packit 0848f5
                            &enumtype, desc, &desc_len, &bind, &readonly, &continuous, &atomic);
Packit 0848f5
        check(full_name_len == name_len);
Packit 0848f5
        check(full_desc_len == desc_len);
Packit 0848f5
Packit 0848f5
        /* regular call, no NULLs; should truncate (with termination) to STR_SZ
Packit 0848f5
         * if necessary, otherwise returns strlen+1 in the corresponding "_len"
Packit 0848f5
         * var */
Packit 0848f5
        name[STR_SZ] = (char) 'Z';
Packit 0848f5
        desc[STR_SZ] = (char) 'Z';
Packit 0848f5
        name_len = desc_len = STR_SZ;
Packit 0848f5
        MPI_T_pvar_get_info(i, name, &name_len, &verb, &varclass, &dtype,
Packit 0848f5
                            &enumtype, desc, &desc_len, &bind, &readonly, &continuous, &atomic);
Packit 0848f5
        check((strlen(name) + 1) == min(name_len, STR_SZ));
Packit 0848f5
        check((strlen(desc) + 1) == min(desc_len, STR_SZ));
Packit 0848f5
        check(name[STR_SZ] == (char) 'Z');
Packit 0848f5
        check(desc[STR_SZ] == (char) 'Z');
Packit 0848f5
Packit 0848f5
        /* pass NULL lengths, string buffers should be left alone */
Packit 0848f5
        for (j = 0; j < STR_SZ; ++j) {
Packit 0848f5
            name[j] = j % CHAR_MAX;
Packit 0848f5
            desc[j] = j % CHAR_MAX;
Packit 0848f5
        }
Packit 0848f5
        MPI_T_pvar_get_info(i, name, /*name_len= */ NULL, &verb, &varclass, &dtype,
Packit 0848f5
                            &enumtype, desc, /*desc_len= */ NULL, &bind, &readonly,
Packit 0848f5
                            &continuous, &atomic);
Packit 0848f5
        for (j = 0; j < STR_SZ; ++j) {
Packit 0848f5
            check(name[j] == j % CHAR_MAX);
Packit 0848f5
            check(desc[j] == j % CHAR_MAX);
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    /* check string handling for categories */
Packit 0848f5
    MPI_T_category_get_num(&num_cat);
Packit 0848f5
    for (i = 0; i < num_cat; ++i) {
Packit 0848f5
        int full_name_len, full_desc_len;
Packit 0848f5
        /* pass NULL string, non-zero lengths; should get full lengths */
Packit 0848f5
        full_name_len = full_desc_len = 1;
Packit 0848f5
        MPI_T_category_get_info(i, NULL, &full_name_len, NULL, &full_desc_len,
Packit 0848f5
                                &num_cvars, &num_pvars, /*num_categories= */ &j);
Packit 0848f5
        check(full_name_len >= 0);
Packit 0848f5
        check(full_desc_len >= 0);
Packit 0848f5
Packit 0848f5
        /* pass non-NULL string, zero lengths; should get full lengths also */
Packit 0848f5
        name_len = desc_len = 0;
Packit 0848f5
        MPI_T_category_get_info(i, name, &name_len, desc, &desc_len,
Packit 0848f5
                                &num_cvars, &num_pvars, /*num_categories= */ &j);
Packit 0848f5
        check(full_name_len == name_len);
Packit 0848f5
        check(full_desc_len == desc_len);
Packit 0848f5
Packit 0848f5
        /* regular call, no NULLs; should truncate (with termination) to STR_SZ
Packit 0848f5
         * if necessary, otherwise returns strlen+1 in the corresponding "_len"
Packit 0848f5
         * var */
Packit 0848f5
        name[STR_SZ] = (char) 'Z';
Packit 0848f5
        desc[STR_SZ] = (char) 'Z';
Packit 0848f5
        name_len = desc_len = STR_SZ;
Packit 0848f5
        MPI_T_category_get_info(i, name, &name_len, desc, &desc_len,
Packit 0848f5
                                &num_cvars, &num_pvars, /*num_categories= */ &j);
Packit 0848f5
        check((strlen(name) + 1) == min(name_len, STR_SZ));
Packit 0848f5
        check((strlen(desc) + 1) == min(desc_len, STR_SZ));
Packit 0848f5
        check(name[STR_SZ] == (char) 'Z');
Packit 0848f5
        check(desc[STR_SZ] == (char) 'Z');
Packit 0848f5
Packit 0848f5
        /* pass NULL lengths, string buffers should be left alone */
Packit 0848f5
        for (j = 0; j < STR_SZ; ++j) {
Packit 0848f5
            name[j] = j % CHAR_MAX;
Packit 0848f5
            desc[j] = j % CHAR_MAX;
Packit 0848f5
        }
Packit 0848f5
        MPI_T_category_get_info(i, name, /*name_len= */ NULL, desc,
Packit 0848f5
                                /*desc_len= */ NULL, &num_cvars, &num_pvars,
Packit 0848f5
                                /*num_categories= */ &j);
Packit 0848f5
        for (j = 0; j < STR_SZ; ++j) {
Packit 0848f5
            check(name[j] == j % CHAR_MAX);
Packit 0848f5
            check(desc[j] == j % CHAR_MAX);
Packit 0848f5
        }
Packit 0848f5
Packit 0848f5
        /* not really a string test, just need a quick spot to stick a test for the
Packit 0848f5
         * existence of the correct MPI_T prototype (tt#1727) */
Packit 0848f5
        {
Packit 0848f5
            int indices[1];
Packit 0848f5
            MPI_T_category_get_pvars(i, 1, indices);
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    MPI_Allreduce(MPI_IN_PLACE, &errs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
Packit 0848f5
    if (rank == 0) {
Packit 0848f5
        if (errs) {
Packit 0848f5
            printf("found %d errors\n", errs);
Packit 0848f5
        }
Packit 0848f5
        else {
Packit 0848f5
            printf(" No errors\n");
Packit 0848f5
        }
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    MPI_T_finalize();
Packit 0848f5
    MPI_Finalize();
Packit 0848f5
Packit 0848f5
    return 0;
Packit 0848f5
}