/* Do not edit this file. It is produced from the corresponding .m4 source */
/*
 *  Copyright (C) 2017, Northwestern University and Argonne National Laboratory
 *  See COPYRIGHT notice in top-level directory.
 */
/* $Id$ */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdlib.h>

#include <pnetcdf.h>
#include <dispatch.h>
#include <pnc_debug.h>
#include <common.h>




#define GET_ONE_COUNT(ndims, count) {                                    \
    int _i;                                                              \
    count = (MPI_Offset*) NCI_Malloc(sizeof(MPI_Offset) * ndims);        \
    for (_i=0; _i<ndims; _i++)                                           \
        count[_i] = 1;                                                   \
}

#define GET_FULL_DIMENSIONS(pncp, varp, start, count) {                       \
    int _i;                                                                   \
    start = (MPI_Offset*) NCI_Malloc(sizeof(MPI_Offset) * varp.ndims * 2);    \
    count = start + varp.ndims;                                               \
                                                                              \
    for (_i=0; _i<varp.ndims; _i++) {                                         \
        count[_i] = varp.shape[_i];                                           \
        start[_i] = 0;                                                        \
    }                                                                         \
    if (varp.recdim >= 0) { /* find current numrec if varp is record var */   \
        MPI_Offset numrecs;                                                   \
        err = pncp->driver->inq_dim(pncp->ncp, varp.recdim, NULL, &numrecs);  \
        if (err != NC_NOERR) {                                                \
            reqMode |= NC_REQ_ZERO;                                           \
            NCI_Free(start);                                                  \
            start = NULL;                                                     \
            count = NULL;                                                     \
        }                                                                     \
        else                                                                  \
            count[0] = numrecs;                                               \
    }                                                                         \
}


/*----< check_EINVALCOORDS() >-----------------------------------------------*/
static
int check_EINVALCOORDS(int        strict_coord_bound,
                       MPI_Offset start,
                       MPI_Offset count,
                       MPI_Offset shape)
{
    if (strict_coord_bound) {
        if (start < 0 || start >= shape)
            DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
    }
    else {
        if (start < 0 || start > shape)
            DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
        if (start == shape && count > 0)
            DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
    }
    return NC_NOERR;
}


typedef enum {
    API_GET,
    API_PUT,
    API_IGET,
    API_IPUT,
    API_BPUT
} IO_type;

/*----< check_EEDGE() >------------------------------------------------------*/
static
int check_EEDGE(const MPI_Offset *start,
                const MPI_Offset *count,
                const MPI_Offset *stride,
                const MPI_Offset *shape)
{
    if (*count > *shape || *start + *count > *shape)
        DEBUG_RETURN_ERROR(NC_EEDGE);
    if (stride == NULL) { /* vars APIs but stride is NULL */
        if (*count > *shape || *start + *count > *shape)
            DEBUG_RETURN_ERROR(NC_EEDGE)
    }
    else { /* for vars/varm APIs */
        if (*count > 0 && *start + (*count - 1) * (*stride) >= *shape)
            DEBUG_RETURN_ERROR(NC_EEDGE)
    }
    return NC_NOERR;
}

#ifdef PNETCDF_DEBUG
#define DEBUG_PRINT_EEDGE(dim) {                                            \
    if (err != NC_NOERR) {                                                  \
        char *_env_str = getenv("PNETCDF_VERBOSE_DEBUG_MODE");              \
        if (_env_str != NULL && *_env_str != '0') {                         \
            char name[1024];                                                \
            int _rank;                                                      \
            MPI_Comm_rank(MPI_COMM_WORLD, &_rank);                          \
            pncp->driver->inq_var(pncp->ncp, varid, name, NULL, NULL,       \
                                  NULL, NULL, NULL, NULL, NULL);            \
            if (stride != NULL)                                             \
                fprintf(stderr, "Rank %d: NC_EEDGE variable %s: shape[%d]=%lld but start[%d]=%lld count[%d]=%lld stride[%d]=%lld\n", \
                _rank, name, dim, shape[dim], dim, start[dim], dim, count[dim], dim, stride[dim]); \
            else                                                            \
                fprintf(stderr, "Rank %d: NC_EEDGE variable %s: shape[%d]=%lld but start[%d]=%lld count[%d]=%lld\n", \
                _rank, name, dim, shape[dim], dim, start[dim], dim, count[dim]); \
        }                                                                   \
    }                                                                       \
}
#else
#define DEBUG_PRINT_EEDGE(dim)
#endif

/*----< check_start_count_stride() >-----------------------------------------*/
static
int check_start_count_stride(PNC              *pncp,
                             int               varid,
                             int               isRead,
                             NC_api            api_kind, /* var1/vara/vars */
                             const MPI_Offset *start,
                             const MPI_Offset *count,
                             const MPI_Offset *stride)
{
    /* only var1, vara, vars, and varm APIs will reach here */
    int i, err, ndims, firstDim;
    MPI_Offset *shape=NULL;

    shape = pncp->vars[varid].shape;
    /* if record variable, obtain the current size of record dimension */
    if (pncp->vars[varid].recdim >= 0) {
        err = pncp->driver->inq_dim(pncp->ncp, pncp->vars[varid].recdim, NULL,
                                    &shape[0]);
        if (err != NC_NOERR) return err;
    }

    /* Check NC_EINVALCOORDS error for argument start[]
     * for API var1/vara/vars/varm, start cannot be NULL, except for scalars
     * and negative start[] is illegal */
    if (start == NULL || start[0] < 0) DEBUG_RETURN_ERROR(NC_EINVALCOORDS)

    firstDim = 0;
    /* check NC_EINVALCOORDS for record dimension */
    if (pncp->vars[varid].recdim >= 0) {
        if ((pncp->format <= NC_FORMAT_CDF2 ||
             pncp->format == NC_FORMAT_NETCDF4_CLASSIC) &&
            start[0] > NC_MAX_UINT)
            /* CDF-1, 2 and netcdf4 classic model */
            DEBUG_RETURN_ERROR(NC_EINVALCOORDS)

        /* for record variable, [0] is the NC_UNLIMITED dimension */
        /* read cannot go beyond current numrecs */
        if (isRead) {
            MPI_Offset len = (count == NULL) ? 1 : count[0];
            if (shape[0] == 0 && len > 0) /* no record yet */
                DEBUG_RETURN_ERROR(NC_EINVALCOORDS)
            err = check_EINVALCOORDS(pncp->flag & NC_MODE_STRICT_COORD_BOUND,
                                     start[0], len, shape[0]);
            if (err != NC_NOERR) return err;
        }
        firstDim = 1; /* done for checking the record dimension */
    }

    /* continue to check NC_EINVALCOORDS for the rest dimensions */
    ndims = pncp->vars[varid].ndims;
    for (i=firstDim; i<ndims; i++) {
        MPI_Offset len = (count == NULL) ? 1 : count[i];
        err = check_EINVALCOORDS(pncp->flag & NC_MODE_STRICT_COORD_BOUND,
                                 start[i], len, shape[i]);
        if (err != NC_NOERR) return err;
    }

    /* check NC_EEDGE error for argument count[] */

    if (count == NULL) {
        if (api_kind == API_VARA || api_kind == API_VARS ||
            api_kind == API_VARM)
            /* vara/vars/varm, count cannot be NULL */
            DEBUG_RETURN_ERROR(NC_EEDGE)
    }
    else {
        firstDim = 0;
        /* check record dimension */
        if (pncp->vars[varid].recdim >= 0) {
            if (count[0] < 0)  /* no negative count[] */
                DEBUG_RETURN_ERROR(NC_ENEGATIVECNT)

            /* for record variable, [0] is the NC_UNLIMITED dimension */
            /* read cannot go beyond current numrecs */
            if (isRead) {
                err = check_EEDGE(start, count, stride, shape);
                DEBUG_PRINT_EEDGE(0)
                if (err != NC_NOERR) return err;
            }
            firstDim = 1; /* skip checking the record dimension */
        }

        /* continue to check NC_EEDGE for the rest dimensions */
        for (i=firstDim; i<ndims; i++) {
            if (shape[i] < 0) DEBUG_RETURN_ERROR(NC_EEDGE)
            if (count[i] < 0) /* no negative count[] */
                DEBUG_RETURN_ERROR(NC_ENEGATIVECNT)
            if (stride == NULL)
                err = check_EEDGE(start+i, count+i, NULL, shape+i);
            else
                err = check_EEDGE(start+i, count+i, stride+i, shape+i);
            DEBUG_PRINT_EEDGE(i)
            if (err != NC_NOERR) return err;
        }

        /* Check NC_ESTRIDE for non-positive values. We did not check
         * stride[i] >= shape[i], as it is caught as NC_EEDGE error above */
        if (stride != NULL) {
            for (i=0; i<ndims; i++) {
                if (stride[i] <= 0) DEBUG_RETURN_ERROR(NC_ESTRIDE)
            }
        }
    }
    return NC_NOERR;
}

/*----< sanity_check() >-----------------------------------------------------*/
static
int sanity_check(PNC          *pncp,
                 int           varid,
                 IO_type       io,       /* get/put/iget/iput/bput */
                 MPI_Datatype  itype,    /* internal data type */
                 int           isColl)   /* collective or indepdnent API */
{
    /* for put APIs */
    if (io == API_PUT || io == API_IPUT || io == API_BPUT)
        /* check file write permission for put APIs */
        if (pncp->flag & NC_MODE_RDONLY) DEBUG_RETURN_ERROR(NC_EPERM)

    /* for blocking APIs */
    if (io == API_PUT || io == API_GET) {
        /* blocking get/put APIs must be called in data mode */
        if (pncp->format != NC_FORMAT_NETCDF4 && (pncp->flag & NC_MODE_DEF))
            DEBUG_RETURN_ERROR(NC_EINDEFINE)

        /* for blocking APIs, check if in collective or independent mode */
        if (isColl) { /* check if file is currently in collective data mode */
            if (pncp->flag & NC_MODE_INDEP) DEBUG_RETURN_ERROR(NC_EINDEP)
        }
        else { /* check if file is currently in independent data mode */
            if (!(pncp->flag & NC_MODE_INDEP)) DEBUG_RETURN_ERROR(NC_ENOTINDEP)
        }
    }

    /* variable NC_GLOBAL is illegal in get/put APIs */
    if (varid == NC_GLOBAL) DEBUG_RETURN_ERROR(NC_EGLOBAL)

    /* check whether variable ID is valid */
    if (varid < 0 || varid >= pncp->nvars) DEBUG_RETURN_ERROR(NC_ENOTVAR)

    /* MPI_DATATYPE_NULL in this case represent a flexible API */
    if (itype == MPI_DATATYPE_NULL) return NC_NOERR;

    /* check itype against xtype for NC_ECHAR */
    if (itype == MPI_CHAR) {
        if (pncp->vars[varid].xtype != NC_CHAR) DEBUG_RETURN_ERROR(NC_ECHAR)
    }
    else {
        if (pncp->vars[varid].xtype == NC_CHAR) DEBUG_RETURN_ERROR(NC_ECHAR)
    }
    return NC_NOERR;
}

/*----< allreduce_error() >--------------------------------------------------*/
/* This subroutine is for safe mode to check errors across all processes */
static
int allreduce_error(PNC *pncp, int err)
{
    int minE, mpireturn;
    TRACE_COMM(MPI_Allreduce)(&err, &minE, 1, MPI_INT, MPI_MIN, pncp->comm);
    if (mpireturn != MPI_SUCCESS)
        return ncmpii_error_mpi2nc(mpireturn, "MPI_Allreduce");
    return minE;
}

/*----< ncmpi_put_var() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var(int ncid,
                     int varid,
                     
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 0);

    

    

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_text(int ncid,
                     int varid,
                     
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_text() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_schar(int ncid,
                     int varid,
                     
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_schar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_uchar(int ncid,
                     int varid,
                     
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_uchar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_short(int ncid,
                     int varid,
                     
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_short() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_ushort(int ncid,
                     int varid,
                     
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_ushort() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_int(int ncid,
                     int varid,
                     
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_int() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_uint(int ncid,
                     int varid,
                     
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_uint() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_long(int ncid,
                     int varid,
                     
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_long() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_float(int ncid,
                     int varid,
                     
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_float() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_double(int ncid,
                     int varid,
                     
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_double() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_longlong(int ncid,
                     int varid,
                     
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_longlong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var_ulonglong(int ncid,
                     int varid,
                     
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_put_var_ulonglong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_put_var_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_all(int ncid,
                     int varid,
                     
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 1);

    

    

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_text_all(int ncid,
                     int varid,
                     
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_text_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_schar_all(int ncid,
                     int varid,
                     
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_schar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_uchar_all(int ncid,
                     int varid,
                     
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_uchar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_short_all(int ncid,
                     int varid,
                     
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_short_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_ushort_all(int ncid,
                     int varid,
                     
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_ushort_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_int_all(int ncid,
                     int varid,
                     
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_int_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_uint_all(int ncid,
                     int varid,
                     
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_uint_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_long_all(int ncid,
                     int varid,
                     
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_long_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_float_all(int ncid,
                     int varid,
                     
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_float_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_double_all(int ncid,
                     int varid,
                     
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_double_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_longlong_all(int ncid,
                     int varid,
                     
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_longlong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var_ulonglong_all(int ncid,
                     int varid,
                     
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_put_var_ulonglong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var(int ncid,
                     int varid,
                     
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 0);

    

    

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_text(int ncid,
                     int varid,
                     
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_text() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_schar(int ncid,
                     int varid,
                     
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_schar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_uchar(int ncid,
                     int varid,
                     
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_uchar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_short(int ncid,
                     int varid,
                     
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_short() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_ushort(int ncid,
                     int varid,
                     
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_ushort() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_int(int ncid,
                     int varid,
                     
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_int() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_uint(int ncid,
                     int varid,
                     
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_uint() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_long(int ncid,
                     int varid,
                     
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_long() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_float(int ncid,
                     int varid,
                     
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_float() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_double(int ncid,
                     int varid,
                     
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_double() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_longlong(int ncid,
                     int varid,
                     
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_longlong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var_ulonglong(int ncid,
                     int varid,
                     
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 0);

    

    

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            if (err != NC_NOERR) return err;
    

    /* call the subroutine that implements ncmpi_get_var_ulonglong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return status;
}

/*----< ncmpi_get_var_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_all(int ncid,
                     int varid,
                     
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 1);

    

    

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_text_all(int ncid,
                     int varid,
                     
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_text_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_schar_all(int ncid,
                     int varid,
                     
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_schar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_uchar_all(int ncid,
                     int varid,
                     
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_uchar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_short_all(int ncid,
                     int varid,
                     
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_short_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_ushort_all(int ncid,
                     int varid,
                     
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_ushort_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_int_all(int ncid,
                     int varid,
                     
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_int_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_uint_all(int ncid,
                     int varid,
                     
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_uint_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_long_all(int ncid,
                     int varid,
                     
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_long_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_float_all(int ncid,
                     int varid,
                     
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_float_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_double_all(int ncid,
                     int varid,
                     
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_double_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_longlong_all(int ncid,
                     int varid,
                     
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_longlong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var_ulonglong_all(int ncid,
                     int varid,
                     
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    
    MPI_Offset *start=NULL, *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 1);

    

    

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (err == NC_NOERR)
            GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
            
    

    /* call the subroutine that implements ncmpi_get_var_ulonglong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (start != NULL) NCI_Free(start);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_text() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_schar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_uchar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_short() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_ushort() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_int() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_uint() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_long() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_float() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_double() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_longlong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_var1_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_ulonglong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_put_var1_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_text_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_schar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_uchar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_short_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_ushort_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_int_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_uint_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_long_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_float_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_double_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_longlong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_var1_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_var1_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_put_var1_ulonglong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_text() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_schar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_uchar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_short() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_ushort() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_int() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_uint() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_long() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_float() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_double() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_longlong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_var1_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_ulonglong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return status;
}

/*----< ncmpi_get_var1_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_text_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_schar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_uchar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_short_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_ushort_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_int_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_uint_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_long_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_float_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_double_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_longlong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_var1_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_var1_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count=NULL;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    if (err == NC_NOERR)
            GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* call the subroutine that implements ncmpi_get_var1_ulonglong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    if (count != NULL) NCI_Free(count);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_text() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_schar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_uchar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_short() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_ushort() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_int() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_uint() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_long() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_float() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_double() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_longlong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vara_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vara_ulonglong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_put_vara_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_text_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_schar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_uchar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_short_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_ushort_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_int_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_uint_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_long_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_float_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_double_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_longlong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vara_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vara_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vara_ulonglong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_text() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_schar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_uchar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_short() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_ushort() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_int() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_uint() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_long() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_float() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_double() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_longlong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vara_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 0);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vara_ulonglong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_get_vara_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_text_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_schar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_uchar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_short_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_ushort_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_int_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_uint_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_long_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_float_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_double_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_longlong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vara_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vara_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 1);

    

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vara_ulonglong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    NULL, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_text() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_schar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_uchar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_short() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_ushort() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_int() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_uint() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_long() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_float() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_double() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_longlong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vars_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_vars_ulonglong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_put_vars_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_text_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_schar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_uchar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_short_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_ushort_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_int_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_uint_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_long_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_float_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_double_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_longlong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_vars_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_vars_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_vars_ulonglong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_text() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_schar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_uchar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_short() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_ushort() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_int() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_uint() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_long() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_float() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_double() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_longlong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vars_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 0);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_vars_ulonglong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_get_vars_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    bufcount, buftype, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_text_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_schar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_uchar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_short_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_ushort_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_int_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_uint_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_long_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_float_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_double_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_longlong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vars_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_vars_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 1);

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_vars_ulonglong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, NULL, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    bufcount, buftype, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_text() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_schar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_uchar() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_short() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_ushort() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_int() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_INT, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_uint() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_long() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_float() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_double() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_longlong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varm_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_put_varm_ulonglong() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_put_varm_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    bufcount, buftype, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_text_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_schar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_uchar_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_short_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_ushort_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_int_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_uint_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_long_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_float_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_double_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_longlong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varm_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varm_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     const unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_put_varm_ulonglong_all() */
    status = pncp->driver->put_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    
    /* independent flexible API, return now if zero-length request */
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    bufcount, buftype, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_text() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_text(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_text() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_schar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_schar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_schar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_uchar() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_uchar(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_uchar() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_short() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_short(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_short() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_ushort() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_ushort(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_ushort() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_int() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_int(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_int() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_INT, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_uint() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_uint(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_uint() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_long() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_long(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_long() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_float() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_float(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_float() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_double() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_double(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_double() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_longlong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_longlong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_longlong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_ulonglong() >---------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varm_ulonglong(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 0);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    
    

    /* call the subroutine that implements ncmpi_get_varm_ulonglong() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return status;
}

/*----< ncmpi_get_varm_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    bufcount, buftype, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_text_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_text_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     char *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_text_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_schar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_schar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     schar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_schar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_uchar_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_uchar_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     uchar *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_uchar_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_CHAR, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_short_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_short_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     short *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_short_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_ushort_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_ushort_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     ushort *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_ushort_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_SHORT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_int_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_int_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     int *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_int_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_uint_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_uint_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     uint *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_uint_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_long_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_long_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_long_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_float_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_float_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     float *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_float_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_FLOAT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_double_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_double_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     double *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_double_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_DOUBLE, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_longlong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_longlong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_longlong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_LONG_LONG_INT, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varm_ulonglong_all() >---------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varm_ulonglong_all(int ncid,
                     int varid,
                     const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                     unsigned long long *buf)
{
    int status, err, reqMode=0;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 1);

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (err == NC_NOERR && pncp->vars[varid].ndims > 0)
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);

    

    
    /* collective APIs and safe mode enabled, check errors across all procs */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    
    

    /* call the subroutine that implements ncmpi_get_varm_ulonglong_all() */
    status = pncp->driver->get_var(pncp->ncp, varid, start, count,
                                    stride, imap, buf,
                                    -1, MPI_UNSIGNED_LONG_LONG, reqMode);

    

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/* ncmpi_get/put_varn_<type>_<mode> API:
 *    type:   data type of I/O buffer, buf
 *    mode:   independent (<nond>) or collective (_all)
 *
 * arguments:
 *    num:    number of start and count pairs
 *    starts: an 2D array of size [num][ndims]. Each starts[i][*] indicates
 *            the starting array indices for a subarray request. ndims is
 *            the number of dimensions of the defined netCDF variable.
 *    counts: an 2D array of size [num][ndims]. Each counts[i][*] indicates
 *            the number of array elements to be accessed. This argument
 *            can be NULL, equivalent to counts with all 1s.
 *    bufcount and buftype: these 2 arguments are only available for flexible
 *            APIs, indicating the I/O buffer memory layout. When buftype is
 *            MPI_DATATYPE_NULL, bufcount is ignored and the data type of buf
 *            is considered matched the variable data type defined in the file.
 */
/*----< ncmpi_put_varn() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, bufcount, buftype, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, bufcount, buftype, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, bufcount, buftype, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, bufcount, buftype, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_text() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_text(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const char *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_text() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_CHAR, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_text_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_text_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const char *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_CHAR, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_text_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_CHAR, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_schar() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_schar(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const schar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_schar() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_schar_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_schar_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const schar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SIGNED_CHAR, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_schar_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_uchar(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const uchar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_uchar() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_uchar_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_uchar_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const uchar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_CHAR, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_uchar_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_short() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_short(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const short *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_short() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SHORT, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_short_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_short_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const short *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_SHORT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_short_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SHORT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_ushort(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const ushort *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_ushort() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_ushort_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_ushort_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const ushort *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_SHORT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_ushort_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_int() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_int(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const int *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_int() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_INT, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_int_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_int_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const int *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_INT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_int_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_INT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_uint() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_uint(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const uint *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_uint() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_uint_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_uint_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const uint *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_uint_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_long() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_long(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_long() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_long_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_long_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_long_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_float() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_float(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const float *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_FLOAT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_float() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_FLOAT, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_float_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_float_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const float *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_FLOAT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_FLOAT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_float_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_FLOAT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_double() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_double(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const double *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_DOUBLE, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_double() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_DOUBLE, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_double_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_double_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const double *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DOUBLE, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_DOUBLE, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_double_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_DOUBLE, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_longlong(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_longlong() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_longlong_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_longlong_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_LONG_LONG_INT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_longlong_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_put_varn_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_varn_ulonglong(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const unsigned long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_ulonglong() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    return status;
}

/*----< ncmpi_put_varn_ulonglong_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_put_varn_ulonglong_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   const unsigned long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_UNSIGNED_LONG_LONG, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements put_var1 */
        status = pncp->driver->put_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_put_varn_ulonglong_all() */
        status = pncp->driver->put_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, bufcount, buftype, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, bufcount, buftype, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, bufcount, buftype, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, bufcount, buftype, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_text() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_text(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   char *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_text() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_CHAR, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_text_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_text_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   char *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_CHAR, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_text_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_CHAR, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_schar() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_schar(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   schar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_schar() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_schar_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_schar_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   schar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SIGNED_CHAR, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_schar_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SIGNED_CHAR, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_uchar(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   uchar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_uchar() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_uchar_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_uchar_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   uchar *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_CHAR, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_uchar_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_CHAR, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_short() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_short(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   short *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_short() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SHORT, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_short_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_short_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   short *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_SHORT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_short_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_SHORT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_ushort(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   ushort *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_ushort() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_ushort_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_ushort_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   ushort *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_SHORT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_ushort_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_SHORT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_int() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_int(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   int *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_int() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_INT, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_int_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_int_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   int *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_INT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_int_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_INT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_uint() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_uint(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   uint *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_uint() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_uint_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_uint_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   uint *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_uint_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_long() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_long(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_long() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_long_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_long_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_long_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_float() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_float(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   float *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_FLOAT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_float() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_FLOAT, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_float_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_float_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   float *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_FLOAT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_FLOAT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_float_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_FLOAT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_double() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_double(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   double *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_DOUBLE, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_double() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_DOUBLE, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_double_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_double_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   double *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DOUBLE, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_DOUBLE, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_double_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_DOUBLE, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_longlong(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_longlong() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_longlong_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_longlong_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_LONG_LONG_INT, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_longlong_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_LONG_LONG_INT, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_varn_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_varn_ulonglong(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   unsigned long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;
    /* for independent API, return now if zero-length request */
    if (num == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_INDEP;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_ulonglong() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    return status;
}

/*----< ncmpi_get_varn_ulonglong_all() >-----------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_get_varn_ulonglong_all(int                ncid,
                   int                varid,
                   int                num,
                   MPI_Offset* const *starts,
                   MPI_Offset* const *counts,
                   unsigned long long *buf)
{
    int i, err, status, reqMode=0, isScalar=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_UNSIGNED_LONG_LONG, 1);
    if (err != NC_NOERR) goto err_check;

    if (num == 0) goto err_check;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        isScalar = 1;
        if (num != 1) DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
    }
    else { /* non-scalar variables */
        /* starts cannot be NULL for non-scalar variables */
        if (starts == NULL) {
            DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
            goto err_check;
        }

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) {
                DEBUG_ASSIGN_ERROR(err, NC_ENULLSTART)
                break;
            }

            /* when counts or counts[i] is NULL, it is equivalent to var1 API */
            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) break;
        }
        if (err != NC_NOERR) goto err_check;
    }

    

err_check:
    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }
    else if (num == 0) /* zero-length request */
        reqMode |= NC_REQ_ZERO;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_HL | NC_REQ_COLL;

    if (isScalar) {
        MPI_Offset start[1]={0}, count[1]={1};
        /* calling the subroutine that implements get_var1 */
        status = pncp->driver->get_var(pncp->ncp, varid, start, count, NULL,
                                        NULL, buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    else {
        /* calling the subroutine that implements ncmpi_get_varn_ulonglong_all() */
        status = pncp->driver->get_varn(pncp->ncp, varid, num, starts, counts,
                                         buf, -1, MPI_UNSIGNED_LONG_LONG, reqMode);
    }
    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_mput_var() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var(int                ncid,
                      int                nvars,
                      int               *varids,
   
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_text(int                ncid,
                      int                nvars,
                      int               *varids,
   
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_short(int                ncid,
                      int                nvars,
                      int               *varids,
   
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_int(int                ncid,
                      int                nvars,
                      int               *varids,
   
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_long(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_float(int                ncid,
                      int                nvars,
                      int               *varids,
   
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_double(int                ncid,
                      int                nvars,
                      int               *varids,
   
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var(int                ncid,
                      int                nvars,
                      int               *varids,
   
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_text(int                ncid,
                      int                nvars,
                      int               *varids,
   
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_short(int                ncid,
                      int                nvars,
                      int               *varids,
   
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_int(int                ncid,
                      int                nvars,
                      int               *varids,
   
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_long(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_float(int                ncid,
                      int                nvars,
                      int               *varids,
   
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_double(int                ncid,
                      int                nvars,
                      int               *varids,
   
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_FULL_DIMENSIONS(pncp, pncp->vars[varids[i]], start, count)
        if (err != NC_NOERR) break;
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(start);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_var1_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_var1_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_var1_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_var1_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_var1_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_var1_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VAR1;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], NULL, stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        GET_ONE_COUNT(pncp->vars[varids[i]].ndims, count)
        start = starts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        NCI_Free(count);
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vara_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vara_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vara_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vara_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vara_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vara_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARA;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_vars_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_vars_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_vars_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_vars_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_vars_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_vars_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARS;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mput_varm_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   void* const *bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   char* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   schar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uchar* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   short* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   ushort* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   int* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uint* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   float* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   double* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mput_varm_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mput_varm_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   unsigned long long* const *bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_PUT, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 0,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iput_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_text() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_text(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_schar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_schar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_uchar() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_uchar(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_short() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_short(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_ushort() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_ushort(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_int() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_int(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_uint() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_uint(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_long() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_long(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_float() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_float(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_double() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_double(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_longlong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_longlong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_ulonglong() >--------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_mget_varm_ulonglong(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    /* for independent API, return now if zero-length request */
    if (nvars == 0) return NC_NOERR;

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 0);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_INDEP;

    /* for independent API, return now if error encountered */
    if (err != NC_NOERR) return err;

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   void **bufs,
                      const MPI_Offset *bufcounts,
                      const MPI_Datatype *buftypes)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DATATYPE_NULL, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
        /* when bufcounts[i] == NC_COUNT_IGNORE, buftypes[i] must be an MPI predefined datatype */
        if (buftypes[i] != MPI_DATATYPE_NULL && bufcounts[i] == NC_COUNT_IGNORE &&
            buftypes[i] != MPI_CHAR          &&
            buftypes[i] != MPI_SIGNED_CHAR   && buftypes[i] != MPI_UNSIGNED_CHAR      &&
            buftypes[i] != MPI_SHORT         && buftypes[i] != MPI_UNSIGNED_SHORT     &&
            buftypes[i] != MPI_INT           && buftypes[i] != MPI_UNSIGNED           &&
            buftypes[i] != MPI_FLOAT         && buftypes[i] != MPI_DOUBLE             &&
            buftypes[i] != MPI_LONG_LONG_INT && buftypes[i] != MPI_UNSIGNED_LONG_LONG &&
            buftypes[i] != MPI_LONG) {
            DEBUG_ASSIGN_ERROR(err, NC_EINVAL)
            break;
        }
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      bufcounts[i],buftypes[i],
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_text_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_text_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   char **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_schar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_schar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   schar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_uchar_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_uchar_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uchar **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_CHAR, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_CHAR,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_short_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_short_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   short **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_ushort_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_ushort_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   ushort **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_SHORT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_SHORT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_int_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_int_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   int **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_uint_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_uint_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   uint **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_long_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_long_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_float_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_float_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   float **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_FLOAT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_FLOAT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_double_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_double_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   double **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_DOUBLE, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_DOUBLE,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_longlong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_longlong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_LONG_LONG_INT, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_LONG_LONG_INT,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_mget_varm_ulonglong_all() >--------------------------------------------*/
/* This API is a collective subroutine. */
int
ncmpi_mget_varm_ulonglong_all(int                ncid,
                      int                nvars,
                      int               *varids,
   MPI_Offset* const *starts,
                      MPI_Offset* const *counts,
                      MPI_Offset* const *strides,
                      MPI_Offset* const *imaps,
   unsigned long long **bufs)
{
    int i, reqMode=0, status=NC_NOERR, err, *reqs;
    PNC *pncp;
    NC_api api_kind=API_VARM;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    

    if (imaps == NULL && strides != NULL) api_kind = API_VARS;
    else if (imaps == NULL && strides == NULL) api_kind = API_VARA;

    for (i=0; i<nvars; i++) {
        err = sanity_check(pncp, varids[i], API_GET, MPI_UNSIGNED_LONG_LONG, 1);
        if (err != NC_NOERR) break;

        /* checks start, count, stride for non-scalars */
        if (pncp->vars[varids[i]].ndims > 0) {
            MPI_Offset *stride=NULL;
            if (strides != NULL) stride = strides[i];
            err = check_start_count_stride(pncp, varids[i], 1,
                                           api_kind, starts[i], counts[i], stride);
            if (err != NC_NOERR) break;
        }
        
    }

    reqMode |= NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL | NC_REQ_COLL;

    
    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        status = pncp->driver->wait(pncp->ncp, 0, NULL, NULL, reqMode);
        return err;
    }

    reqs = (int*) NCI_Malloc(sizeof(int) * nvars);
    for (i=0; i<nvars; i++) {
        MPI_Offset *start, *count, *stride=NULL, *imap=NULL;

        /* call the nonblocking subroutines */
        start = starts[i]; count = counts[i];
        if (strides != NULL) stride = strides[i];
        if (imaps != NULL) imap = imaps[i];

        err = pncp->driver->iget_var(pncp->ncp, varids[i], start, count,
                                      stride, imap, bufs[i],
                                      -1, MPI_UNSIGNED_LONG_LONG,
                                      &reqs[i], reqMode);
        
        if (err != NC_NOERR) break;
    }
    status = pncp->driver->wait(pncp->ncp, i, reqs, NULL, reqMode);
    NCI_Free(reqs);

    return (err != NC_NOERR) ? err : status;
}

/*----< ncmpi_iput_var() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var(int ncid,
                   int varid,
                   
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    

    

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_text(int ncid,
                   int varid,
                   
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_text() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_schar(int ncid,
                   int varid,
                   
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_schar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_uchar(int ncid,
                   int varid,
                   
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_uchar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_short(int ncid,
                   int varid,
                   
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_short() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_ushort(int ncid,
                   int varid,
                   
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_ushort() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_int(int ncid,
                   int varid,
                   
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_int() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_uint(int ncid,
                   int varid,
                   
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_uint() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_long(int ncid,
                   int varid,
                   
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_long() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_float(int ncid,
                   int varid,
                   
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_float() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_double(int ncid,
                   int varid,
                   
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_double() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_longlong(int ncid,
                   int varid,
                   
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_longlong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var_ulonglong(int ncid,
                   int varid,
                   
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iput_var_ulonglong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var(int ncid,
                   int varid,
                   
                   void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    

    

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_text(int ncid,
                   int varid,
                   
                   char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_text() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_schar(int ncid,
                   int varid,
                   
                   schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_schar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_uchar(int ncid,
                   int varid,
                   
                   uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_uchar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_short(int ncid,
                   int varid,
                   
                   short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_short() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_ushort(int ncid,
                   int varid,
                   
                   ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_ushort() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_int(int ncid,
                   int varid,
                   
                   int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_int() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_uint(int ncid,
                   int varid,
                   
                   uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_uint() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_long(int ncid,
                   int varid,
                   
                   long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_long() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_float(int ncid,
                   int varid,
                   
                   float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_float() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_double(int ncid,
                   int varid,
                   
                   double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_double() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_longlong(int ncid,
                   int varid,
                   
                   long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_longlong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iget_var_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var_ulonglong(int ncid,
                   int varid,
                   
                   unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_iget_var_ulonglong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var(int ncid,
                   int varid,
                   
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    reqMode |= NC_REQ_WR | NC_REQ_FLEX;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_text(int ncid,
                   int varid,
                   
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_text() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_schar(int ncid,
                   int varid,
                   
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_schar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_uchar(int ncid,
                   int varid,
                   
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_uchar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_short(int ncid,
                   int varid,
                   
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_short() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_ushort(int ncid,
                   int varid,
                   
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_ushort() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_int(int ncid,
                   int varid,
                   
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_int() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_uint(int ncid,
                   int varid,
                   
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_uint() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_long(int ncid,
                   int varid,
                   
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_long() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_float(int ncid,
                   int varid,
                   
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_float() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_double(int ncid,
                   int varid,
                   
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_double() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_longlong(int ncid,
                   int varid,
                   
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_longlong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_bput_var_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var_ulonglong(int ncid,
                   int varid,
                   
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    
    MPI_Offset *start, *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_FULL_DIMENSIONS(pncp, pncp->vars[varid], start, count)
     if (err != NC_NOERR) return err;

    /* calling the subroutine that implements ncmpi_bput_var_ulonglong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    NCI_Free(start);
    return err;
}

/*----< ncmpi_iput_var1() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_text() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_schar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_uchar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_short() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_ushort() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_int() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_uint() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_long() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_float() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_double() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_longlong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_var1_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_var1_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iput_var1_ulonglong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_text() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_schar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_uchar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_short() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_ushort() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_int() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_uint() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_long() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_float() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_double() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_longlong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iget_var1_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_var1_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_iget_var1_ulonglong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    reqMode |= NC_REQ_WR | NC_REQ_FLEX;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_text() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_schar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_uchar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_short() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_ushort() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_int() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_uint() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_long() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_float() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_double() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_longlong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_bput_var1_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_var1_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VAR1;
    MPI_Offset *count;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, NULL, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    GET_ONE_COUNT(pncp->vars[varid].ndims, count)

    /* calling the subroutine that implements ncmpi_bput_var1_ulonglong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    NCI_Free(count);
    return err;
}

/*----< ncmpi_iput_vara() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_iput_vara() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_text() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_schar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_uchar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_short() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_ushort() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_int() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_uint() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_long() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_float() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_double() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_longlong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vara_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vara_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vara_ulonglong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_iget_vara() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_text() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_schar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_uchar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_short() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_ushort() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_int() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_uint() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_long() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_float() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_double() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_longlong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vara_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vara_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vara_ulonglong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    reqMode |= NC_REQ_WR | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_bput_vara() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_text() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_schar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_uchar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_short() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_ushort() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_int() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_uint() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_long() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_float() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_double() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_longlong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vara_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vara_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARA;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, NULL);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vara_ulonglong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 NULL, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_iput_vars() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_text() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_schar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_uchar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_short() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_ushort() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_int() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_uint() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_long() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_float() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_double() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_longlong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_vars_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_vars_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_vars_ulonglong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_iget_vars() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_text() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_schar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_uchar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_short() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_ushort() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_int() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_uint() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_long() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_float() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_double() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_longlong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_vars_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_vars_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_vars_ulonglong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    reqMode |= NC_REQ_WR | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_bput_vars() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_text() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_schar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_uchar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_short() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_ushort() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_int() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_uint() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_long() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_float() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_double() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_longlong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_vars_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_vars_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARS;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_vars_ulonglong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, NULL, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_iput_varm() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_text() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_schar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_uchar() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_short() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_ushort() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_int() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_uint() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_long() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_float() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_double() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_longlong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iput_varm_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varm_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iput_varm_ulonglong() */
    err = pncp->driver->iput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_iget_varm() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_text() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_schar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_uchar() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_short() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_ushort() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_int() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_uint() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_long() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_float() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_double() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_longlong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_iget_varm_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varm_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 1, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_iget_varm_ulonglong() */
    err = pncp->driver->iget_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    reqMode |= NC_REQ_WR | NC_REQ_FLEX;

    

    /* calling the subroutine that implements ncmpi_bput_varm() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 bufcount, buftype, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_text() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_text(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const char *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_text() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_schar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_schar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const schar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_schar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_SIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_uchar() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_uchar(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const uchar *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_uchar() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_CHAR, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_short() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_short(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const short *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_short() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_ushort() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_ushort(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const ushort *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_ushort() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_SHORT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_int() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_int(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const int *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_int() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_uint() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_uint(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const uint *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_uint() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_long() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_long(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_long() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_LONG, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_float() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_float(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const float *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_float() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_FLOAT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_double() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_double(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const double *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_double() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_DOUBLE, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_longlong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_longlong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_longlong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_LONG_LONG_INT, reqid, reqMode);

    
    return err;
}

/*----< ncmpi_bput_varm_ulonglong() >-----------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varm_ulonglong(int ncid,
                   int varid,
                   const MPI_Offset *start,
                   const MPI_Offset *count,
                   const MPI_Offset *stride,
                   const MPI_Offset *imap,
                   const unsigned long long *buf,
                   int *reqid)
{
    int err, reqMode;
    PNC *pncp;
    NC_api api_kind=API_VARM;
    

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (imap == NULL && stride != NULL) api_kind = API_VARS;
    else if (imap == NULL && stride == NULL) api_kind = API_VARA;

    /* not-scalar variable checks start, count, stride */
    if (pncp->vars[varid].ndims > 0) {
        err = check_start_count_stride(pncp, varid, 0, api_kind,
                                       start, count, stride);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    

    /* calling the subroutine that implements ncmpi_bput_varm_ulonglong() */
    err = pncp->driver->bput_var(pncp->ncp, varid, start, count,
                                 stride, imap, buf,
                                 -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);

    
    return err;
}

/* ncmpi_iget/iput_varn_<type>_<mode> API:
 *    type:   data type of I/O buffer, buf
 *    mode:   indpendent (<nond>) or collective (_all)
 *
 * arguments:
 *    num:    number of start and count pairs
 *    starts: an 2D array of size [num][ndims]. Each starts[i][*] indicates
 *            the starting array indices for a subarray request. ndims is
 *            the number of dimensions of the defined netCDF variable.
 *    counts: an 2D array of size [num][ndims]. Each counts[i][*] indicates
 *            the number of array elements to be accessed. This argument
 *            can be NULL, equivalent to counts with all 1s.
 *    bufcount and buftype: these 2 arguments are only available for flexible
 *            APIs, indicating the I/O buffer memory layout. When buftype is
 *            MPI_DATATYPE_NULL, bufcount is ignored and the data type of buf
 *            is considered matched the variable data type defined in the file.
 *    reqid:  request ID returned to user
 */
/*----< ncmpi_iget_varn() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_FLEX;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, bufcount, buftype, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, bufcount, buftype, reqid, reqMode);
}

/*----< ncmpi_iget_varn_text() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_text(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 char *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_text() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_CHAR, reqid, reqMode);
}

/*----< ncmpi_iget_varn_schar() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_schar(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 schar *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_SIGNED_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_schar() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_SIGNED_CHAR, reqid, reqMode);
}

/*----< ncmpi_iget_varn_uchar() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_uchar(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 uchar *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_uchar() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_CHAR, reqid, reqMode);
}

/*----< ncmpi_iget_varn_short() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_short(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 short *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_SHORT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_short() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_SHORT, reqid, reqMode);
}

/*----< ncmpi_iget_varn_ushort() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_ushort(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 ushort *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_SHORT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_ushort() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_SHORT, reqid, reqMode);
}

/*----< ncmpi_iget_varn_int() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_int(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 int *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_INT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_int() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_INT, reqid, reqMode);
}

/*----< ncmpi_iget_varn_uint() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_uint(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 uint *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_uint() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED, reqid, reqMode);
}

/*----< ncmpi_iget_varn_long() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_long(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_LONG, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_long() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_LONG, reqid, reqMode);
}

/*----< ncmpi_iget_varn_float() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_float(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 float *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_FLOAT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_float() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_FLOAT, reqid, reqMode);
}

/*----< ncmpi_iget_varn_double() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_double(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 double *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_DOUBLE, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_double() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_DOUBLE, reqid, reqMode);
}

/*----< ncmpi_iget_varn_longlong() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_longlong(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 long long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_LONG_LONG_INT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_longlong() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_LONG_LONG_INT, reqid, reqMode);
}

/*----< ncmpi_iget_varn_ulonglong() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iget_varn_ulonglong(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 unsigned long long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IGET, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_RD | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iget_var1 */
        return pncp->driver->iget_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 1,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iget_varn_ulonglong() */
    return pncp->driver->iget_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);
}

/*----< ncmpi_iput_varn() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_FLEX;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, bufcount, buftype, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, bufcount, buftype, reqid, reqMode);
}

/*----< ncmpi_iput_varn_text() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_text(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const char *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_text() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_CHAR, reqid, reqMode);
}

/*----< ncmpi_iput_varn_schar() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_schar(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const schar *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_SIGNED_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_schar() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_SIGNED_CHAR, reqid, reqMode);
}

/*----< ncmpi_iput_varn_uchar() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_uchar(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const uchar *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_uchar() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_CHAR, reqid, reqMode);
}

/*----< ncmpi_iput_varn_short() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_short(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const short *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_SHORT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_short() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_SHORT, reqid, reqMode);
}

/*----< ncmpi_iput_varn_ushort() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_ushort(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const ushort *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_SHORT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_ushort() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_SHORT, reqid, reqMode);
}

/*----< ncmpi_iput_varn_int() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_int(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const int *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_INT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_int() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_INT, reqid, reqMode);
}

/*----< ncmpi_iput_varn_uint() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_uint(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const uint *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_uint() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED, reqid, reqMode);
}

/*----< ncmpi_iput_varn_long() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_long(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_LONG, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_long() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_LONG, reqid, reqMode);
}

/*----< ncmpi_iput_varn_float() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_float(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const float *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_FLOAT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_float() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_FLOAT, reqid, reqMode);
}

/*----< ncmpi_iput_varn_double() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_double(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const double *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_DOUBLE, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_double() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_DOUBLE, reqid, reqMode);
}

/*----< ncmpi_iput_varn_longlong() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_longlong(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const long long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_LONG_LONG_INT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_longlong() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_LONG_LONG_INT, reqid, reqMode);
}

/*----< ncmpi_iput_varn_ulonglong() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_iput_varn_ulonglong(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const unsigned long long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_IPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    

    

    

    
    reqMode = NC_REQ_WR | NC_REQ_NBI | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements iput_var1 */
        return pncp->driver->iput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_iput_varn_ulonglong() */
    return pncp->driver->iput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);
}

/*----< ncmpi_bput_varn() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const void *buf,
                             MPI_Offset bufcount, MPI_Datatype buftype,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DATATYPE_NULL, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    
    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        return NC_EINVAL;

    reqMode |= NC_REQ_WR | NC_REQ_FLEX;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, bufcount, buftype, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, bufcount, buftype, reqid, reqMode);
}

/*----< ncmpi_bput_varn_text() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_text(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const char *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_text() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_CHAR, reqid, reqMode);
}

/*----< ncmpi_bput_varn_schar() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_schar(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const schar *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_SIGNED_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_schar() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_SIGNED_CHAR, reqid, reqMode);
}

/*----< ncmpi_bput_varn_uchar() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_uchar(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const uchar *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_CHAR, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_CHAR, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_uchar() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_CHAR, reqid, reqMode);
}

/*----< ncmpi_bput_varn_short() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_short(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const short *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_SHORT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_SHORT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_short() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_SHORT, reqid, reqMode);
}

/*----< ncmpi_bput_varn_ushort() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_ushort(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const ushort *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_SHORT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_SHORT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_ushort() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_SHORT, reqid, reqMode);
}

/*----< ncmpi_bput_varn_int() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_int(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const int *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_INT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_INT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_int() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_INT, reqid, reqMode);
}

/*----< ncmpi_bput_varn_uint() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_uint(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const uint *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_uint() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED, reqid, reqMode);
}

/*----< ncmpi_bput_varn_long() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_long(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_LONG, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_long() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_LONG, reqid, reqMode);
}

/*----< ncmpi_bput_varn_float() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_float(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const float *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_FLOAT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_FLOAT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_float() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_FLOAT, reqid, reqMode);
}

/*----< ncmpi_bput_varn_double() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_double(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const double *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_DOUBLE, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_DOUBLE, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_double() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_DOUBLE, reqid, reqMode);
}

/*----< ncmpi_bput_varn_longlong() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_longlong(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const long long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_LONG_LONG_INT, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_LONG_LONG_INT, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_longlong() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_LONG_LONG_INT, reqid, reqMode);
}

/*----< ncmpi_bput_varn_ulonglong() >--------------------------------------------------*/
/* This API is an independent subroutine, which can be called in either
 * collective or independent data mode or even in define mode.
 */
int
ncmpi_bput_varn_ulonglong(int                ncid,
                 int                varid,
                 int                num,
                 MPI_Offset* const *starts,
                 MPI_Offset* const *counts,
                 const unsigned long long *buf,
                 int               *reqid)
{
    int i, err, reqMode;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    if (reqid != NULL) *reqid = NC_REQ_NULL;

    err = sanity_check(pncp, varid, API_BPUT, MPI_UNSIGNED_LONG_LONG, 0);
    if (err != NC_NOERR) return err;

    if (num == 0) return NC_NOERR;

    
#ifdef ENABLE_BURST_BUFFER
    if (pncp->driver == ncbbio_inq_driver())
        reqMode = NC_REQ_NBI;
    else
#endif
    { /* check if buffer has been attached */
        MPI_Offset buf_size;
        reqMode = NC_REQ_NBB;
        err = pncp->driver->inq_misc(pncp->ncp, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, NULL, NULL,
                                     NULL, NULL, NULL, NULL, &buf_size);
        if (err != NC_NOERR) return err;
    }

    

    

    reqMode |= NC_REQ_WR | NC_REQ_HL;

    if (pncp->vars[varid].ndims == 0) { /* scalar variable */
        MPI_Offset start[1]={0}, count[1]={1};

        if (num != 1) DEBUG_RETURN_ERROR(NC_EINVAL)

        /* starts can be NULL. If not starts[0][0] should be 0 */
        /* calling the subroutine that implements bput_var1 */
        return pncp->driver->bput_var(pncp->ncp, varid, start, count, NULL,
                                      NULL, buf, -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);
    }
    else { /* non-scalar variables */
        if (starts == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

        for (i=0; i<num; i++) { /* check starts and counts */
            NC_api api;
            MPI_Offset *count;
            if (starts[i] == NULL) DEBUG_RETURN_ERROR(NC_ENULLSTART)

            if (counts == NULL || counts[i] == NULL) {
                api = API_VAR1;
                count = NULL;
            } else {
                api = API_VARA;
                count = counts[i];
            }
            err = check_start_count_stride(pncp, varid, 0,
                                           api, starts[i], count, NULL);
            if (err != NC_NOERR) return err;
        }
    }

    /* calling the subroutine that implements ncmpi_bput_varn_ulonglong() */
    return pncp->driver->bput_varn(pncp->ncp, varid, num, starts, counts,
                                   buf, -1, MPI_UNSIGNED_LONG_LONG, reqid, reqMode);
}


/*----< ncmpi_put_vard() >--------------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vard(int           ncid,
                int           varid,
                MPI_Datatype  filetype,  /* access layout to the variable in file */
                const void *buf,
                MPI_Offset    bufcount,
                MPI_Datatype  buftype)   /* data type of the buffer */
{
    int err, status, reqMode=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 0);

    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered or zero request */
    if (err != NC_NOERR) return err;
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    /* calling the subroutine that implements ncmpi_put_vard() */
    status = pncp->driver->put_vard(pncp->ncp, varid, filetype, buf,
                                   bufcount, buftype, reqMode);

    return status;
}

/*----< ncmpi_put_vard_all() >--------------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_put_vard_all(int           ncid,
                int           varid,
                MPI_Datatype  filetype,  /* access layout to the variable in file */
                const void *buf,
                MPI_Offset    bufcount,
                MPI_Datatype  buftype)   /* data type of the buffer */
{
    int err, status, reqMode=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_PUT, MPI_DATATYPE_NULL, 1);

    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_WR | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    /* calling the subroutine that implements ncmpi_put_vard_all() */
    status = pncp->driver->put_vard(pncp->ncp, varid, filetype, buf,
                                   bufcount, buftype, reqMode);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

/*----< ncmpi_get_vard() >--------------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vard(int           ncid,
                int           varid,
                MPI_Datatype  filetype,  /* access layout to the variable in file */
                void *buf,
                MPI_Offset    bufcount,
                MPI_Datatype  buftype)   /* data type of the buffer */
{
    int err, status, reqMode=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 0);

    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* for independent API, return now if error encountered or zero request */
    if (err != NC_NOERR) return err;
    if (buftype != MPI_DATATYPE_NULL && bufcount == 0) return NC_NOERR;

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_INDEP;

    /* calling the subroutine that implements ncmpi_get_vard() */
    status = pncp->driver->get_vard(pncp->ncp, varid, filetype, buf,
                                   bufcount, buftype, reqMode);

    return status;
}

/*----< ncmpi_get_vard_all() >--------------------------------------------------*/
/* This API is an independent subroutine. */
int
ncmpi_get_vard_all(int           ncid,
                int           varid,
                MPI_Datatype  filetype,  /* access layout to the variable in file */
                void *buf,
                MPI_Offset    bufcount,
                MPI_Datatype  buftype)   /* data type of the buffer */
{
    int err, status, reqMode=0;
    PNC *pncp;

    /* check if ncid is valid.
     * For invalid ncid, we must return error now, as there is no way to
     * continue with invalid ncp. However, collective APIs might hang if this
     * error occurs only on a subset of processes
     */
    err = PNC_check_id(ncid, &pncp);
    if (err != NC_NOERR) return err;

    err = sanity_check(pncp, varid, API_GET, MPI_DATATYPE_NULL, 1);

    /* when bufcount == NC_COUNT_IGNORE, buftype must be an MPI predefined datatype */
    if (err == NC_NOERR &&
        buftype != MPI_DATATYPE_NULL && bufcount == NC_COUNT_IGNORE &&
        buftype != MPI_CHAR          &&
        buftype != MPI_SIGNED_CHAR   && buftype != MPI_UNSIGNED_CHAR      &&
        buftype != MPI_SHORT         && buftype != MPI_UNSIGNED_SHORT     &&
        buftype != MPI_INT           && buftype != MPI_UNSIGNED           &&
        buftype != MPI_FLOAT         && buftype != MPI_DOUBLE             &&
        buftype != MPI_LONG_LONG_INT && buftype != MPI_UNSIGNED_LONG_LONG &&
        buftype != MPI_LONG)
        DEBUG_ASSIGN_ERROR(err, NC_EINVAL)

    /* In safe mode, check errors across all processes */
    if (pncp->flag & NC_MODE_SAFE) {
        err = allreduce_error(pncp, err);
        if (err != NC_NOERR) return err;
    }
    else if (err == NC_EPERM || err == NC_EINDEFINE || err == NC_EINDEP ||
             err == NC_ENOTINDEP) /* cannot continue if fatal errors */
        return err;
    else if (err != NC_NOERR) { /* other errors, participate collective call */
        int nprocs;
        MPI_Comm_size(pncp->comm, &nprocs);
        if (nprocs == 1) return err;
        reqMode |= NC_REQ_ZERO;
    }

    reqMode |= NC_REQ_RD | NC_REQ_BLK | NC_REQ_FLEX | NC_REQ_COLL;

    /* calling the subroutine that implements ncmpi_get_vard_all() */
    status = pncp->driver->get_vard(pncp->ncp, varid, filetype, buf,
                                   bufcount, buftype, reqMode);

    return (err != NC_NOERR) ? err : status; /* first error encountered */
}

