Blame src/env/mpivars.c

Packit Service c5cf8c
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2014 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
/* style:allow:snprintf:9 sig:0 */
Packit Service c5cf8c
/* style:allow:strncpy:3 sig:0 */
Packit Service c5cf8c
/* style:allow:fprintf:26 sig:0 */
Packit Service c5cf8c
/* style:allow:free:3 sig:0 */
Packit Service c5cf8c
/* style:allow:malloc:3 sig:0 */
Packit Service c5cf8c
Packit Service c5cf8c
#include <stdio.h>
Packit Service c5cf8c
#include <string.h>
Packit Service c5cf8c
#include <stdlib.h>
Packit Service c5cf8c
#include "mpi.h"
Packit Service c5cf8c
Packit Service c5cf8c
/* At least one early implementation of MPIT failed to set the
Packit Service c5cf8c
   enumtype and thus dirty data was returned.  This should not be needed,
Packit Service c5cf8c
   but is provided in case an implementation returns too many
Packit Service c5cf8c
   bogus results.  In that case, define NEEDS_MPIT_ENUM_LIMIT */
Packit Service c5cf8c
#ifdef NEEDS_MPIT_ENUM_LIMIT
Packit Service c5cf8c
#define MAX_ENUM_NUMBER 10
Packit Service c5cf8c
#endif
Packit Service c5cf8c
Packit Service c5cf8c
/* Lengths for statically allocated character arrays */
Packit Service c5cf8c
#define MAX_NAME_LEN 128
Packit Service c5cf8c
#define MAX_DESC_LEN 1024
Packit Service c5cf8c
Packit Service c5cf8c
/* Function Prototypes */
Packit Service c5cf8c
/* Top level routines for printing MPI_T variables */
Packit Service c5cf8c
int PrintControlVars(FILE * fp);
Packit Service c5cf8c
int PrintPerfVars(FILE * fp);
Packit Service c5cf8c
int PrintCategories(FILE * fp);
Packit Service c5cf8c
Packit Service c5cf8c
/* Functions to print MPI_T objects */
Packit Service c5cf8c
int PrintEnum(FILE * fp, MPI_T_enum enumtype);
Packit Service c5cf8c
Packit Service c5cf8c
/* Functions to convert enums or handles to strings for printing */
Packit Service c5cf8c
const char *mpit_scopeToStr(int scope);
Packit Service c5cf8c
const char *mpit_bindingToStr(int binding);
Packit Service c5cf8c
const char *mpit_validDtypeStr(MPI_Datatype datatype);
Packit Service c5cf8c
const char *mpit_varclassToStr(int varClass);
Packit Service c5cf8c
const char *mpit_verbosityToStr(int verbosity);
Packit Service c5cf8c
const char *mpit_errclasscheck(int err);
Packit Service c5cf8c
Packit Service c5cf8c
/* Function to convert MPI_T variables to strings for printing */
Packit Service c5cf8c
int getCvarValueAsStr(int idx, MPI_Datatype dataytpe, char varValue[], int varValueLen);
Packit Service c5cf8c
int getPvarValueAsStr(int idx, MPI_Datatype datatype, int isContinuous,
Packit Service c5cf8c
                      char varValue[], int varValueLen);
Packit Service c5cf8c
Packit Service c5cf8c
/* Functions for checking on correctness */
Packit Service c5cf8c
int perfCheckVarType(int varClass, MPI_Datatype datatype);
Packit Service c5cf8c
int checkStringLen(const char *str, int expectedLen, const char *strName);
Packit Service c5cf8c
Packit Service c5cf8c
/* Variable descriptions are sometimes long - this variable controls
Packit Service c5cf8c
   whether they are printed */
Packit Service c5cf8c
static int showDesc = 1;
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char *argv[])
Packit Service c5cf8c
{
Packit Service c5cf8c
    int required, provided, i, wrank;
Packit Service c5cf8c
    required = MPI_THREAD_SINGLE;
Packit Service c5cf8c
Packit Service c5cf8c
    /* The MPI standard permits MPI_T_init_thread to be called before or
Packit Service c5cf8c
     * after MPI_Init_thread.  In some cases, a user may need to
Packit Service c5cf8c
     * call MPI_T_init_thread and set some MPI_T variables before calling
Packit Service c5cf8c
     * MPI_Init_thread to change the behavior of the initialization. */
Packit Service c5cf8c
    MPI_Init_thread(&argc, &argv, required, &provided);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_T_init_thread(required, &provided);
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Comm_rank(MPI_COMM_WORLD, &wrank);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Check for a few command-line controls */
Packit Service c5cf8c
    /* Assumes that all processes see this */
Packit Service c5cf8c
    for (i = 1; i < argc; i++) {
Packit Service c5cf8c
        /* Check for "no descriptions" */
Packit Service c5cf8c
        if (strcmp(argv[i], "--nodesc") == 0 || strcmp(argv[i], "-nodesc") == 0)
Packit Service c5cf8c
            showDesc = 0;
Packit Service c5cf8c
        else {
Packit Service c5cf8c
            if (wrank == 0) {
Packit Service c5cf8c
                fprintf(stderr, "Unrecognized command line argument %s\n", argv[i]);
Packit Service c5cf8c
                fprintf(stderr, "Usage: mpivars [ -nodesc ]\n");
Packit Service c5cf8c
                MPI_Abort(MPI_COMM_WORLD, 1);
Packit Service c5cf8c
                return 1;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    PrintControlVars(stdout);
Packit Service c5cf8c
    fprintf(stdout, "\n");
Packit Service c5cf8c
    PrintPerfVars(stdout);
Packit Service c5cf8c
    fprintf(stdout, "\n");
Packit Service c5cf8c
    PrintCategories(stdout);
Packit Service c5cf8c
Packit Service c5cf8c
    /* Finalize MPI_T before MPI in case MPI_Finalize checks for any
Packit Service c5cf8c
     * allocated resources (MPICH can be configured to do this) */
Packit Service c5cf8c
    MPI_T_finalize();
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_Finalize();
Packit Service c5cf8c
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Print all of the MPI_T control variables, along with their major properties
Packit Service c5cf8c
   and if possible a value (if possible depends on both the complexity of the
Packit Service c5cf8c
   variable and whether a value is defined) */
Packit Service c5cf8c
int PrintControlVars(FILE * fp)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, num_cvar, nameLen, verbosity, descLen, binding, scope;
Packit Service c5cf8c
    int hasValue;
Packit Service c5cf8c
    char name[MAX_NAME_LEN], desc[MAX_DESC_LEN], varValue[512];
Packit Service c5cf8c
    MPI_T_enum enumtype;
Packit Service c5cf8c
    MPI_Datatype datatype;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_T_cvar_get_num(&num_cvar);
Packit Service c5cf8c
    fprintf(fp, "%d MPI Control Variables\n", num_cvar);
Packit Service c5cf8c
    for (i = 0; i < num_cvar; i++) {
Packit Service c5cf8c
        hasValue = 0;
Packit Service c5cf8c
        nameLen = sizeof(name);
Packit Service c5cf8c
        descLen = sizeof(desc);
Packit Service c5cf8c
        MPI_T_cvar_get_info(i, name, &nameLen, &verbosity, &datatype,
Packit Service c5cf8c
                            &enumtype, desc, &descLen, &binding, &scope);
Packit Service c5cf8c
        /* Check on correct output */
Packit Service c5cf8c
        checkStringLen(desc, descLen, "descLen");
Packit Service c5cf8c
Packit Service c5cf8c
        /* Attempt to get a value */
Packit Service c5cf8c
        if (binding == MPI_T_BIND_NO_OBJECT) {
Packit Service c5cf8c
            hasValue = getCvarValueAsStr(i, datatype, varValue, sizeof(varValue));
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        if (hasValue) {
Packit Service c5cf8c
            fprintf(fp, "\t%-32s=%s\t%s\t%s\t%s\t%s\t%s\n", name, varValue,
Packit Service c5cf8c
                    mpit_scopeToStr(scope),
Packit Service c5cf8c
                    mpit_bindingToStr(binding),
Packit Service c5cf8c
                    mpit_validDtypeStr(datatype),
Packit Service c5cf8c
                    mpit_verbosityToStr(verbosity), showDesc ? desc : "");
Packit Service c5cf8c
        } else {
Packit Service c5cf8c
            fprintf(fp, "\t%-32s\t%s\t%s\t%s\t%s\t%s\n", name,
Packit Service c5cf8c
                    mpit_scopeToStr(scope),
Packit Service c5cf8c
                    mpit_bindingToStr(binding),
Packit Service c5cf8c
                    mpit_validDtypeStr(datatype),
Packit Service c5cf8c
                    mpit_verbosityToStr(verbosity), showDesc ? desc : "");
Packit Service c5cf8c
        }
Packit Service c5cf8c
        if (datatype == MPI_INT && enumtype != MPI_T_ENUM_NULL) {
Packit Service c5cf8c
            PrintEnum(fp, enumtype);
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Print all of the MPI_T performance variables, along with their
Packit Service c5cf8c
   major properties and if possible a value (if possible depends on
Packit Service c5cf8c
   both the complexity of the variable and whether a value is
Packit Service c5cf8c
   defined) */
Packit Service c5cf8c
int PrintPerfVars(FILE * fp)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, numPvar, nameLen, descLen, verbosity, varClass;
Packit Service c5cf8c
    int binding, isReadonly, isContinuous, isAtomic;
Packit Service c5cf8c
    char name[MAX_NAME_LEN], desc[MAX_DESC_LEN], varValue[512];
Packit Service c5cf8c
    MPI_T_enum enumtype;
Packit Service c5cf8c
    MPI_Datatype datatype;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_T_pvar_get_num(&numPvar);
Packit Service c5cf8c
    fprintf(fp, "%d MPI Performance Variables\n", numPvar);
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < numPvar; i++) {
Packit Service c5cf8c
        nameLen = sizeof(name);
Packit Service c5cf8c
        descLen = sizeof(desc);
Packit Service c5cf8c
        MPI_T_pvar_get_info(i, name, &nameLen, &verbosity, &varClass,
Packit Service c5cf8c
                            &datatype, &enumtype, desc, &descLen, &binding,
Packit Service c5cf8c
                            &isReadonly, &isContinuous, &isAtomic);
Packit Service c5cf8c
        /* Check for correct return values */
Packit Service c5cf8c
        checkStringLen(name, nameLen, "nameLen");
Packit Service c5cf8c
        perfCheckVarType(varClass, datatype);
Packit Service c5cf8c
Packit Service c5cf8c
        fprintf(fp, "\t%-32s\t%s\t%s\t%s\t%s\tReadonly=%s\tContinuous=%s\tAtomic=%s\t%s\n",
Packit Service c5cf8c
                name,
Packit Service c5cf8c
                mpit_varclassToStr(varClass),
Packit Service c5cf8c
                mpit_bindingToStr(binding),
Packit Service c5cf8c
                mpit_validDtypeStr(datatype),
Packit Service c5cf8c
                mpit_verbosityToStr(verbosity),
Packit Service c5cf8c
                isReadonly ? "T" : "F",
Packit Service c5cf8c
                isContinuous ? "T" : "F", isAtomic ? "T" : "F", showDesc ? desc : "");
Packit Service c5cf8c
Packit Service c5cf8c
        if (getPvarValueAsStr(i, datatype, isContinuous, varValue, sizeof(varValue))) {
Packit Service c5cf8c
            fprintf(fp, "\tValue = %s\n", varValue);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* A special case for MPI_INT */
Packit Service c5cf8c
        if (datatype == MPI_INT && enumtype != MPI_T_ENUM_NULL) {
Packit Service c5cf8c
            PrintEnum(fp, enumtype);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Print the categories of MPI_T variables defined by the implementation. */
Packit Service c5cf8c
int PrintCategories(FILE * fp)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, j, numCat, nameLen, descLen, numCvars, numPvars, numSubcat;
Packit Service c5cf8c
    char name[MAX_NAME_LEN], desc[MAX_DESC_LEN];
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_T_category_get_num(&numCat);
Packit Service c5cf8c
    if (numCat > 0)
Packit Service c5cf8c
        fprintf(fp, "%d MPI_T categories\n", numCat);
Packit Service c5cf8c
    else
Packit Service c5cf8c
        fprintf(fp, "No categories defined\n");
Packit Service c5cf8c
Packit Service c5cf8c
    for (i = 0; i < numCat; i++) {
Packit Service c5cf8c
        nameLen = sizeof(name);
Packit Service c5cf8c
        descLen = sizeof(desc);
Packit Service c5cf8c
        MPI_T_category_get_info(i, name, &nameLen, desc, &descLen, &numCvars,
Packit Service c5cf8c
                                &numPvars, &numSubcat);
Packit Service c5cf8c
        /* Check on correct output */
Packit Service c5cf8c
        checkStringLen(name, nameLen, "nameLen");
Packit Service c5cf8c
Packit Service c5cf8c
        if (numCvars > 0 || numPvars > 0 || numSubcat > 0) {
Packit Service c5cf8c
            fprintf(fp,
Packit Service c5cf8c
                    "Category %s has %d control variables, %d performance variables, and %d subcategories\n",
Packit Service c5cf8c
                    name, numCvars, numPvars, numSubcat);
Packit Service c5cf8c
        } else {
Packit Service c5cf8c
            fprintf(fp, "Category %s defined but has no content\n", name);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* Output information about the categories */
Packit Service c5cf8c
        if (numCvars > 0) {
Packit Service c5cf8c
            int *cvarIndex = (int *) malloc(numCvars * sizeof(int));
Packit Service c5cf8c
            MPI_T_category_get_cvars(i, numCvars, cvarIndex);
Packit Service c5cf8c
            fprintf(fp, "\tControl Variables:\n");
Packit Service c5cf8c
            for (j = 0; j < numCvars; j++) {
Packit Service c5cf8c
                int varnameLen, verbose, binding, scope;
Packit Service c5cf8c
                MPI_Datatype datatype;
Packit Service c5cf8c
                char varname[MAX_NAME_LEN];
Packit Service c5cf8c
                varnameLen = sizeof(varname);
Packit Service c5cf8c
                MPI_T_cvar_get_info(cvarIndex[j], varname, &varnameLen,
Packit Service c5cf8c
                                    &verbose, &datatype, NULL, NULL, NULL, &binding, &scope);
Packit Service c5cf8c
                fprintf(fp, "\t%-32s:\t%s\t%s\t%s\t%s\n", varname,
Packit Service c5cf8c
                        mpit_scopeToStr(scope),
Packit Service c5cf8c
                        mpit_bindingToStr(binding),
Packit Service c5cf8c
                        mpit_validDtypeStr(datatype), mpit_verbosityToStr(verbose));
Packit Service c5cf8c
            }
Packit Service c5cf8c
            free(cvarIndex);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        if (numPvars > 0) {
Packit Service c5cf8c
            int *pvarIndex = (int *) malloc(numPvars * sizeof(int));
Packit Service c5cf8c
            MPI_T_category_get_pvars(i, numPvars, pvarIndex);
Packit Service c5cf8c
            fprintf(fp, "\tPerformance Variables:\n");
Packit Service c5cf8c
            for (j = 0; j < numPvars; j++) {
Packit Service c5cf8c
                int varnameLen, verbose, binding, varclass;
Packit Service c5cf8c
                int isReadonly, isContinuous, isAtomic;
Packit Service c5cf8c
                MPI_Datatype datatype;
Packit Service c5cf8c
                char varname[MAX_NAME_LEN];
Packit Service c5cf8c
                varnameLen = sizeof(varname);
Packit Service c5cf8c
                MPI_T_pvar_get_info(pvarIndex[j], varname, &varnameLen,
Packit Service c5cf8c
                                    &verbose, &varclass, &datatype,
Packit Service c5cf8c
                                    NULL, NULL, NULL, &binding,
Packit Service c5cf8c
                                    &isReadonly, &isContinuous, &isAtomic);
Packit Service c5cf8c
                fprintf(fp, "\t%-32s:\t%s\t%s\t%s\t%s\n", varname,
Packit Service c5cf8c
                        mpit_varclassToStr(varclass),
Packit Service c5cf8c
                        mpit_bindingToStr(binding),
Packit Service c5cf8c
                        mpit_validDtypeStr(datatype), mpit_verbosityToStr(verbose));
Packit Service c5cf8c
            }
Packit Service c5cf8c
            free(pvarIndex);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        if (numSubcat > 0) {
Packit Service c5cf8c
            int *subcatIndex = (int *) malloc(numSubcat * sizeof(int));
Packit Service c5cf8c
            MPI_T_category_get_categories(i, numSubcat, subcatIndex);
Packit Service c5cf8c
            fprintf(fp, "\tSubcategories:\n");
Packit Service c5cf8c
            for (j = 0; j < numSubcat; j++) {
Packit Service c5cf8c
                int catnameLen, ncvars, npvars, nsubcats;
Packit Service c5cf8c
                char catname[MAX_NAME_LEN];
Packit Service c5cf8c
                catnameLen = sizeof(catname);
Packit Service c5cf8c
                MPI_T_category_get_info(subcatIndex[j], catname, &catnameLen,
Packit Service c5cf8c
                                        NULL, NULL, &ncvars, &npvars, &nsubcats);
Packit Service c5cf8c
                fprintf(fp, "\t%s\n", catname);
Packit Service c5cf8c
            }
Packit Service c5cf8c
            free(subcatIndex);
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Print any MPI_T enum values defined by the implementation. */
Packit Service c5cf8c
int PrintEnum(FILE * fp, MPI_T_enum enumtype)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int i, enumber, enameLen, enumval;
Packit Service c5cf8c
    char ename[MAX_NAME_LEN];
Packit Service c5cf8c
Packit Service c5cf8c
    enameLen = sizeof(ename);
Packit Service c5cf8c
    MPI_T_enum_get_info(enumtype, &enumber, ename, &enameLen);
Packit Service c5cf8c
Packit Service c5cf8c
    fprintf(fp, "Enum %s (%d) values: ", ename, enumber);
Packit Service c5cf8c
#ifdef MAX_ENUM_NUMBER
Packit Service c5cf8c
    if (enumber > MAX_ENUM_NUMBER) {
Packit Service c5cf8c
        fprintf(stderr, "Max number of enum values = %d, > max permitted of %d\n",
Packit Service c5cf8c
                enumber, MAX_ENUM_NUMBER);
Packit Service c5cf8c
        enumber = MAX_ENUM_NUMBER;
Packit Service c5cf8c
    }
Packit Service c5cf8c
#endif
Packit Service c5cf8c
    for (i = 0; i < enumber; i++) {
Packit Service c5cf8c
        enameLen = sizeof(ename);
Packit Service c5cf8c
        MPI_T_enum_get_item(enumtype, i, &enumval, ename, &enameLen);
Packit Service c5cf8c
        fprintf(fp, "%s(%d)%c", ename, enumval, (i != enumber - 1) ? ',' : ' ');
Packit Service c5cf8c
    }
Packit Service c5cf8c
    fprintf(fp, "\n");
Packit Service c5cf8c
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* --- Support routines --- */
Packit Service c5cf8c
Packit Service c5cf8c
const char *mpit_scopeToStr(int scope)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *p = 0;
Packit Service c5cf8c
    switch (scope) {
Packit Service c5cf8c
        case MPI_T_SCOPE_CONSTANT:
Packit Service c5cf8c
            p = "SCOPE_CONSTANT";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_SCOPE_READONLY:
Packit Service c5cf8c
            p = "SCOPE_READONLY";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_SCOPE_LOCAL:
Packit Service c5cf8c
            p = "SCOPE_LOCAL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_SCOPE_GROUP:
Packit Service c5cf8c
            p = "SCOPE_GROUP";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_SCOPE_GROUP_EQ:
Packit Service c5cf8c
            p = "SCOPE_GROUP_EQ";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_SCOPE_ALL:
Packit Service c5cf8c
            p = "SCOPE_ALL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_SCOPE_ALL_EQ:
Packit Service c5cf8c
            p = "SCOPE_ALL_EQ";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        default:
Packit Service c5cf8c
            p = "Unrecoginized scope";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return p;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
const char *mpit_bindingToStr(int binding)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *p;
Packit Service c5cf8c
    switch (binding) {
Packit Service c5cf8c
        case MPI_T_BIND_NO_OBJECT:
Packit Service c5cf8c
            p = "No-object";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_COMM:
Packit Service c5cf8c
            p = "MPI_COMM";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_DATATYPE:
Packit Service c5cf8c
            p = "MPI_DATATYPE";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_ERRHANDLER:
Packit Service c5cf8c
            p = "MPI_ERRHANDLER";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_FILE:
Packit Service c5cf8c
            p = "MPI_FILE";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_GROUP:
Packit Service c5cf8c
            p = "MPI_GROUP";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_OP:
Packit Service c5cf8c
            p = "MPI_OP";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_REQUEST:
Packit Service c5cf8c
            p = "MPI_REQUEST";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_WIN:
Packit Service c5cf8c
            p = "MPI_WIN";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_MESSAGE:
Packit Service c5cf8c
            p = "MPI_MESSAGE";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_BIND_MPI_INFO:
Packit Service c5cf8c
            p = "MPI_INFO";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        default:
Packit Service c5cf8c
            p = "Unknown object binding";
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return p;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
const char *mpit_varclassToStr(int varClass)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *p = 0;
Packit Service c5cf8c
    switch (varClass) {
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_STATE:
Packit Service c5cf8c
            p = "CLASS_STATE";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_LEVEL:
Packit Service c5cf8c
            p = "CLASS_LEVEL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_SIZE:
Packit Service c5cf8c
            p = "CLASS_SIZE";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_PERCENTAGE:
Packit Service c5cf8c
            p = "CLASS_PERCENTAGE";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_HIGHWATERMARK:
Packit Service c5cf8c
            p = "CLASS_HIGHWATERMARK";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_LOWWATERMARK:
Packit Service c5cf8c
            p = "CLASS_LOWWATERMARK";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_COUNTER:
Packit Service c5cf8c
            p = "CLASS_COUNTER";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_AGGREGATE:
Packit Service c5cf8c
            p = "CLASS_AGGREGATE";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_TIMER:
Packit Service c5cf8c
            p = "CLASS_TIMER";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_GENERIC:
Packit Service c5cf8c
            p = "CLASS_GENERIC";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        default:
Packit Service c5cf8c
            p = "Unrecognized pvar class";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return p;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
const char *mpit_validDtypeStr(MPI_Datatype datatype)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *p = 0;
Packit Service c5cf8c
    if (datatype == MPI_INT)
Packit Service c5cf8c
        p = "MPI_INT";
Packit Service c5cf8c
    else if (datatype == MPI_UNSIGNED)
Packit Service c5cf8c
        p = "MPI_UNSIGNED";
Packit Service c5cf8c
    else if (datatype == MPI_UNSIGNED_LONG)
Packit Service c5cf8c
        p = "MPI_UNSIGNED_LONG";
Packit Service c5cf8c
    else if (datatype == MPI_UNSIGNED_LONG_LONG)
Packit Service c5cf8c
        p = "MPI_UNSIGNED_LONG_LONG";
Packit Service c5cf8c
    else if (datatype == MPI_COUNT)
Packit Service c5cf8c
        p = "MPI_COUNT";
Packit Service c5cf8c
    else if (datatype == MPI_CHAR)
Packit Service c5cf8c
        p = "MPI_CHAR";
Packit Service c5cf8c
    else if (datatype == MPI_DOUBLE)
Packit Service c5cf8c
        p = "MPI_DOUBLE";
Packit Service c5cf8c
    else {
Packit Service c5cf8c
        if (datatype == MPI_DATATYPE_NULL) {
Packit Service c5cf8c
            p = "Invalid MPI datatype:NULL";
Packit Service c5cf8c
        } else {
Packit Service c5cf8c
            static char typename[MPI_MAX_OBJECT_NAME + 9];
Packit Service c5cf8c
            int tlen;
Packit Service c5cf8c
            strncpy(typename, "Invalid:", MPI_MAX_OBJECT_NAME);
Packit Service c5cf8c
            MPI_Type_get_name(datatype, typename + 8, &tlen);
Packit Service c5cf8c
            /* We must check location typename[8] to see if
Packit Service c5cf8c
             * MPI_Type_get_name returned a name (not all datatypes
Packit Service c5cf8c
             * have names).  If it did not, then we indicate that
Packit Service c5cf8c
             * with a different message */
Packit Service c5cf8c
            if (typename[8])
Packit Service c5cf8c
                p = typename;
Packit Service c5cf8c
            else
Packit Service c5cf8c
                p = "Invalid: Unknown datatype name";
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    return p;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
const char *mpit_verbosityToStr(int verbosity)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *p = 0;
Packit Service c5cf8c
    switch (verbosity) {
Packit Service c5cf8c
        case MPI_T_VERBOSITY_USER_BASIC:
Packit Service c5cf8c
            p = "VERBOSITY_USER_BASIC";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_USER_DETAIL:
Packit Service c5cf8c
            p = "VERBOSITY_USER_DETAIL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_USER_ALL:
Packit Service c5cf8c
            p = "VERBOSITY_USER_ALL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_TUNER_BASIC:
Packit Service c5cf8c
            p = "VERBOSITY_TUNER_BASIC";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_TUNER_DETAIL:
Packit Service c5cf8c
            p = "VERBOSITY_TUNER_DETAIL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_TUNER_ALL:
Packit Service c5cf8c
            p = "VERBOSITY_TUNER_ALL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_MPIDEV_BASIC:
Packit Service c5cf8c
            p = "VERBOSITY_MPIDEV_BASIC";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_MPIDEV_DETAIL:
Packit Service c5cf8c
            p = "VERBOSITY_MPIDEV_DETAIL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_VERBOSITY_MPIDEV_ALL:
Packit Service c5cf8c
            p = "VERBOSITY_MPIDEV_ALL";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        default:
Packit Service c5cf8c
            p = "Invalid verbosity";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return p;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Provide English strings for the MPI_T error codes */
Packit Service c5cf8c
const char *mpit_errclasscheck(int err)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *p = 0;
Packit Service c5cf8c
    switch (err) {
Packit Service c5cf8c
        case MPI_T_ERR_CVAR_SET_NOT_NOW:
Packit Service c5cf8c
            p = "MPI_T cvar not set";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_CVAR_SET_NEVER:
Packit Service c5cf8c
            p = "MPI_T cvar was never set";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_PVAR_NO_STARTSTOP:
Packit Service c5cf8c
            p = "MPI_T pvar does not support start and stop";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_PVAR_NO_WRITE:
Packit Service c5cf8c
            p = "MPI_T pvar cannot be written";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_PVAR_NO_ATOMIC:
Packit Service c5cf8c
            p = "MPI_T pvar not atomic";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_MEMORY:
Packit Service c5cf8c
            p = "MPI_T out of memory";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_NOT_INITIALIZED:
Packit Service c5cf8c
            p = "MPI_T not initialized";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_CANNOT_INIT:
Packit Service c5cf8c
            p = "MPI_T not initializable";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_INVALID_INDEX:
Packit Service c5cf8c
            p = "MPI_T index invalid";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_INVALID_ITEM:
Packit Service c5cf8c
            p = "MPI_T item index out of range";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_INVALID_HANDLE:
Packit Service c5cf8c
            p = "MPI_T handle invalid";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_OUT_OF_HANDLES:
Packit Service c5cf8c
            p = "MPI_T out of handles";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_OUT_OF_SESSIONS:
Packit Service c5cf8c
            p = "MPI_T out of sessions";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        case MPI_T_ERR_INVALID_SESSION:
Packit Service c5cf8c
            p = "MPI_T invalid session";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
        default:
Packit Service c5cf8c
            p = "Unknown MPI_T_ERR class";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return p;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Read a control variable value and return the value as a null terminated
Packit Service c5cf8c
   string.
Packit Service c5cf8c
   For numeric values, only return a value for scalars (count == 1).
Packit Service c5cf8c
   For character data, return the string if it fits in the available space.
Packit Service c5cf8c
*/
Packit Service c5cf8c
int getCvarValueAsStr(int idx, MPI_Datatype datatype, char varValue[], int varValueLen)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int count, hasValue = 0;
Packit Service c5cf8c
    int ival;
Packit Service c5cf8c
    unsigned uval;
Packit Service c5cf8c
    unsigned long ulval;
Packit Service c5cf8c
    unsigned long long ullval;
Packit Service c5cf8c
    MPI_T_cvar_handle chandle;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_T_cvar_handle_alloc(idx, NULL, &chandle, &count);
Packit Service c5cf8c
    if (count == 1 || (datatype == MPI_CHAR && count < varValueLen)) {
Packit Service c5cf8c
        if (MPI_INT == datatype) {
Packit Service c5cf8c
            MPI_T_cvar_read(chandle, &ival);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%d", ival);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_UNSIGNED == datatype) {
Packit Service c5cf8c
            MPI_T_cvar_read(chandle, &uval);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%u", uval);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_UNSIGNED_LONG == datatype) {
Packit Service c5cf8c
            MPI_T_cvar_read(chandle, &ulval);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%lu", ulval);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_UNSIGNED_LONG_LONG == datatype) {
Packit Service c5cf8c
            MPI_T_cvar_read(chandle, &ullval);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%llu", ullval);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_CHAR == datatype) {
Packit Service c5cf8c
            MPI_T_cvar_read(chandle, varValue);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
    MPI_T_cvar_handle_free(&chandle);
Packit Service c5cf8c
Packit Service c5cf8c
    return hasValue;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Read a performance variable value and return the value as a null terminated
Packit Service c5cf8c
   string.
Packit Service c5cf8c
   For numeric values, only return a value for scalars (count == 1).
Packit Service c5cf8c
   For character data, return the string if it fits in the available space.
Packit Service c5cf8c
*/
Packit Service c5cf8c
int getPvarValueAsStr(int idx, MPI_Datatype datatype, int isContinuous,
Packit Service c5cf8c
                      char varValue[], int varValueLen)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int err, count, hasValue = 0;
Packit Service c5cf8c
    int ival;
Packit Service c5cf8c
    unsigned uval;
Packit Service c5cf8c
    unsigned long ulval;
Packit Service c5cf8c
    unsigned long long ullval;
Packit Service c5cf8c
    double dval;
Packit Service c5cf8c
    MPI_T_pvar_session session;
Packit Service c5cf8c
    MPI_T_pvar_handle phandle;
Packit Service c5cf8c
Packit Service c5cf8c
    MPI_T_pvar_session_create(&session);
Packit Service c5cf8c
    MPI_T_pvar_handle_alloc(session, idx, NULL, &phandle, &count);
Packit Service c5cf8c
    if (count == 1 || (datatype == MPI_CHAR && count < varValueLen)) {
Packit Service c5cf8c
        if (!isContinuous) {
Packit Service c5cf8c
            err = MPI_T_pvar_start(session, phandle);
Packit Service c5cf8c
            if (err != MPI_SUCCESS) {
Packit Service c5cf8c
                strncpy(varValue, "Failed to start pvar", varValueLen);
Packit Service c5cf8c
                goto fn_fail;
Packit Service c5cf8c
            }
Packit Service c5cf8c
            err = MPI_T_pvar_stop(session, phandle);
Packit Service c5cf8c
            if (err != MPI_SUCCESS) {
Packit Service c5cf8c
                strncpy(varValue, "Failed to stop pvar", varValueLen);
Packit Service c5cf8c
                goto fn_fail;
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
        if (MPI_INT == datatype) {
Packit Service c5cf8c
            MPI_T_pvar_read(session, phandle, &ival);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%d", ival);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_UNSIGNED == datatype) {
Packit Service c5cf8c
            MPI_T_pvar_read(session, phandle, &uval);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%u", uval);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_UNSIGNED_LONG == datatype) {
Packit Service c5cf8c
            MPI_T_pvar_read(session, phandle, &ulval);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%lu", ulval);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_UNSIGNED_LONG_LONG == datatype) {
Packit Service c5cf8c
            MPI_T_pvar_read(session, phandle, &ullval);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%llu", ullval);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_DOUBLE == datatype) {
Packit Service c5cf8c
            MPI_T_pvar_read(session, phandle, &dval);
Packit Service c5cf8c
            snprintf(varValue, varValueLen, "%e", dval);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        } else if (MPI_CHAR == datatype) {
Packit Service c5cf8c
            MPI_T_pvar_read(session, phandle, varValue);
Packit Service c5cf8c
            hasValue = 1;
Packit Service c5cf8c
        }
Packit Service c5cf8c
    }
Packit Service c5cf8c
  fn_fail:
Packit Service c5cf8c
    MPI_T_pvar_handle_free(session, &phandle);
Packit Service c5cf8c
    MPI_T_pvar_session_free(&session);
Packit Service c5cf8c
Packit Service c5cf8c
    return hasValue;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
Packit Service c5cf8c
/* Confirm that the datatype is valid for the given performance variable type */
Packit Service c5cf8c
int perfCheckVarType(int varClass, MPI_Datatype datatype)
Packit Service c5cf8c
{
Packit Service c5cf8c
    const char *p = 0;
Packit Service c5cf8c
    switch (varClass) {
Packit Service c5cf8c
            /* INT only */
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_STATE:
Packit Service c5cf8c
            if (datatype != MPI_INT) {
Packit Service c5cf8c
                p = "Invalid datatype for CLASS_STATE: %s\n";
Packit Service c5cf8c
            }
Packit Service c5cf8c
            break;
Packit Service c5cf8c
Packit Service c5cf8c
            /* Arithmetic */
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_LEVEL:
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_SIZE:
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_HIGHWATERMARK:
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_LOWWATERMARK:
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_AGGREGATE:
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_TIMER:
Packit Service c5cf8c
            if (datatype != MPI_UNSIGNED && datatype != MPI_UNSIGNED_LONG &&
Packit Service c5cf8c
                datatype != MPI_UNSIGNED_LONG_LONG && datatype != MPI_DOUBLE)
Packit Service c5cf8c
                p = "Invalid datatype for arithmetic valued class: %s\n";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
            /* DOUBLE only */
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_PERCENTAGE:
Packit Service c5cf8c
            if (datatype != MPI_DOUBLE)
Packit Service c5cf8c
                p = "Invalid datatype for CLASS_PERCENTAGE: %s\n";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
Packit Service c5cf8c
            /* Integer valued */
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_COUNTER:
Packit Service c5cf8c
            if (datatype != MPI_UNSIGNED && datatype != MPI_UNSIGNED_LONG &&
Packit Service c5cf8c
                datatype != MPI_UNSIGNED_LONG_LONG)
Packit Service c5cf8c
                p = "Invalid datatype for integer valued CLASS_COUNTER: %s\n";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
Packit Service c5cf8c
            /* Any */
Packit Service c5cf8c
        case MPI_T_PVAR_CLASS_GENERIC:
Packit Service c5cf8c
            break;
Packit Service c5cf8c
Packit Service c5cf8c
        default:
Packit Service c5cf8c
            p = "Invalid class! (datatype = %s)\n";
Packit Service c5cf8c
            break;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    if (p) {
Packit Service c5cf8c
        const char *p1 = 0;
Packit Service c5cf8c
        if (datatype == MPI_INT)
Packit Service c5cf8c
            p1 = "MPI_INT";
Packit Service c5cf8c
        else if (datatype == MPI_UNSIGNED)
Packit Service c5cf8c
            p1 = "MPI_UNSIGNED";
Packit Service c5cf8c
        else if (datatype == MPI_UNSIGNED_LONG)
Packit Service c5cf8c
            p1 = "MPI_UNSIGNED_LONG";
Packit Service c5cf8c
        else if (datatype == MPI_UNSIGNED_LONG_LONG)
Packit Service c5cf8c
            p1 = "MPI_UNSIGNED_LONG_LONG";
Packit Service c5cf8c
        else if (datatype == MPI_COUNT)
Packit Service c5cf8c
            p1 = "MPI_COUNT";
Packit Service c5cf8c
        else if (datatype == MPI_CHAR)
Packit Service c5cf8c
            p1 = "MPI_CHAR";
Packit Service c5cf8c
        else if (datatype == MPI_DOUBLE)
Packit Service c5cf8c
            p1 = "MPI_DOUBLE";
Packit Service c5cf8c
        else {
Packit Service c5cf8c
            if (datatype == MPI_DATATYPE_NULL) {
Packit Service c5cf8c
                p1 = "Invalid MPI datatype:NULL";
Packit Service c5cf8c
            } else {
Packit Service c5cf8c
                static char typename[MPI_MAX_OBJECT_NAME];
Packit Service c5cf8c
                int tlen;
Packit Service c5cf8c
                MPI_Type_get_name(datatype, typename, &tlen);
Packit Service c5cf8c
                if (typename[0])
Packit Service c5cf8c
                    p1 = typename;
Packit Service c5cf8c
                else
Packit Service c5cf8c
                    p1 = "Invalid: Unknown datatype name";
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
        fprintf(stderr, p, p1);
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}
Packit Service c5cf8c
Packit Service c5cf8c
/* Several of the MPI_T routines return a string length as well as the string.
Packit Service c5cf8c
   Test that the value returned is correct (yes, at least one implementation
Packit Service c5cf8c
   got this wrong). */
Packit Service c5cf8c
int checkStringLen(const char *str, int expectedLen, const char *strName)
Packit Service c5cf8c
{
Packit Service c5cf8c
    int actLen = strlen(str) + 1;
Packit Service c5cf8c
    if (expectedLen != actLen) {
Packit Service c5cf8c
        fprintf(stderr,
Packit Service c5cf8c
                "Incorrect return value for %s = %d, should = %d\n", strName, expectedLen, actLen);
Packit Service c5cf8c
        return 1;
Packit Service c5cf8c
    }
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}