darshan-mpiio.c 53.3 KB
Newer Older
Philip Carns's avatar
Philip Carns committed
1
/*
Shane Snyder's avatar
Shane Snyder committed
2 3 4
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
Philip Carns's avatar
Philip Carns committed
5 6
 */

7 8 9
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE

Philip Carns's avatar
Philip Carns committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include "darshan-runtime-config.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <search.h>
#include <assert.h>
#include <pthread.h>

#include "darshan.h"
Shane Snyder's avatar
Shane Snyder committed
26
#include "darshan-dynamic.h"
Philip Carns's avatar
Philip Carns committed
27

28
/* The mpiio_file_record_ref structure maintains necessary runtime metadata
29
 * for the MPIIO file record (darshan_mpiio_file structure, defined in
30
 * darshan-mpiio-log-format.h) pointed to by 'file_rec'. This metadata
31 32 33 34 35 36
 * assists with the instrumenting of specific statistics in the file record.
 *
 * RATIONALE: the MPIIO module needs to track some stateful, volatile 
 * information about each open file (like the current file offset, most recent 
 * access time, etc.) to aid in instrumentation, but this information can't be
 * stored in the darshan_mpiio_file struct because we don't want it to appear in
37 38 39 40
 * the final darshan log file.  We therefore associate a mpiio_file_record_ref
 * struct with each darshan_mpiio_file struct in order to track this information
 * (i.e., the mapping between mpiio_file_record_ref structs to darshan_mpiio_file
 * structs is one-to-one).
41
 *
42 43 44 45 46 47 48
 * NOTE: we use the 'darshan_record_ref' interface (in darshan-common) to
 * associate different types of handles with this mpiio_file_record_ref struct.
 * This allows us to index this struct (and the underlying file record) by using
 * either the corresponding Darshan record identifier (derived from the filename)
 * or by a generated MPI file handle, for instance. So, while there should only
 * be a single Darshan record identifier that indexes a mpiio_file_record_ref,
 * there could be multiple open file handles that index it.
49
 */
50
struct mpiio_file_record_ref
Philip Carns's avatar
Philip Carns committed
51
{
52
    struct darshan_mpiio_file *file_rec;
Shane Snyder's avatar
Shane Snyder committed
53
    enum darshan_io_type last_io_type;
54 55 56
    double last_meta_end;
    double last_read_end;
    double last_write_end;
57 58
    void *access_root;
    int access_count;
Philip Carns's avatar
Philip Carns committed
59 60
};

61 62 63 64
/* The mpiio_runtime structure maintains necessary state for storing
 * MPI-IO file records and for coordinating with darshan-core at 
 * shutdown time.
 */
Philip Carns's avatar
Philip Carns committed
65 66
struct mpiio_runtime
{
67 68 69
    void *rec_id_hash;
    void *fh_hash;
    int file_rec_count;
Philip Carns's avatar
Philip Carns committed
70 71
};

72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
static void mpiio_runtime_initialize(
    void);
static struct mpiio_file_record_ref *mpiio_track_new_file_record(
    darshan_record_id rec_id, const char *path);
static void mpiio_finalize_file_records(
    void *rec_ref_p);
static void mpiio_record_reduction_op(
    void* infile_v, void* inoutfile_v, int *len, MPI_Datatype *datatype);
static void mpiio_shared_record_variance(
    MPI_Comm mod_comm, struct darshan_mpiio_file *inrec_array,
    struct darshan_mpiio_file *outrec_array, int shared_rec_count);
static void mpiio_cleanup_runtime(
    void);

static void mpiio_shutdown(
    MPI_Comm mod_comm, darshan_record_id *shared_recs,
    int shared_rec_count, void **mpiio_buf, int *mpiio_buf_sz);

90 91
/* extern DXT function defs */
extern void dxt_mpiio_write(darshan_record_id rec_id, int64_t length,
92
    double start_time, double end_time);
93
extern void dxt_mpiio_read(darshan_record_id rec_id, int64_t length,
94 95
    double start_time, double end_time);

Philip Carns's avatar
Philip Carns committed
96 97 98
static struct mpiio_runtime *mpiio_runtime = NULL;
static pthread_mutex_t mpiio_runtime_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static int my_rank = -1;
99
static int enable_dxt_io_trace = 0;
Philip Carns's avatar
Philip Carns committed
100

101 102 103
#define MPIIO_LOCK() pthread_mutex_lock(&mpiio_runtime_mutex)
#define MPIIO_UNLOCK() pthread_mutex_unlock(&mpiio_runtime_mutex)

104 105
#define MPIIO_PRE_RECORD() do { \
    MPIIO_LOCK(); \
106
    if(!darshan_core_disabled_instrumentation()) { \
107 108 109
        if(!mpiio_runtime) { \
            mpiio_runtime_initialize(); \
        } \
110
        if(mpiio_runtime) break; \
111
    } \
112 113
    MPIIO_UNLOCK(); \
    return(ret); \
114 115 116 117 118 119
} while(0)

#define MPIIO_POST_RECORD() do { \
    MPIIO_UNLOCK(); \
} while(0)

120
#define MPIIO_RECORD_OPEN(__ret, __path, __fh, __comm, __mode, __info, __tm1, __tm2) do { \
121 122 123
    darshan_record_id rec_id; \
    struct mpiio_file_record_ref *rec_ref; \
    char *newpath; \
124 125
    int comm_size; \
    if(__ret != MPI_SUCCESS) break; \
126 127 128 129 130 131 132 133
    newpath = darshan_clean_file_path(__path); \
    if(!newpath) newpath = (char *)__path; \
    if(darshan_core_excluded_path(newpath)) { \
        if(newpath != __path) free(newpath); \
        break; \
    } \
    rec_id = darshan_core_gen_record_id(newpath); \
    rec_ref = darshan_lookup_record_ref(mpiio_runtime->rec_id_hash, &rec_id, sizeof(darshan_record_id)); \
134
    if(!rec_ref) rec_ref = mpiio_track_new_file_record(rec_id, newpath); \
135 136 137
    if(!rec_ref) { \
        if(newpath != __path) free(newpath); \
        break; \
138
    } \
139
    rec_ref->file_rec->counters[MPIIO_MODE] = __mode; \
140 141
    DARSHAN_MPI_CALL(PMPI_Comm_size)(__comm, &comm_size); \
    if(comm_size == 1) \
142
        rec_ref->file_rec->counters[MPIIO_INDEP_OPENS] += 1; \
143
    else \
144
        rec_ref->file_rec->counters[MPIIO_COLL_OPENS] += 1; \
145
    if(__info != MPI_INFO_NULL) \
146 147 148 149 150 151 152 153
        rec_ref->file_rec->counters[MPIIO_HINTS] += 1; \
    if(rec_ref->file_rec->fcounters[MPIIO_F_OPEN_TIMESTAMP] == 0 || \
     rec_ref->file_rec->fcounters[MPIIO_F_OPEN_TIMESTAMP] > __tm1) \
        rec_ref->file_rec->fcounters[MPIIO_F_OPEN_TIMESTAMP] = __tm1; \
    DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[MPIIO_F_META_TIME], \
        __tm1, __tm2, rec_ref->last_meta_end); \
    darshan_add_record_ref(&(mpiio_runtime->fh_hash), &__fh, sizeof(MPI_File), rec_ref); \
    if(newpath != __path) free(newpath); \
154 155
} while(0)

156
#define MPIIO_RECORD_READ(__ret, __fh, __count, __datatype, __counter, __tm1, __tm2) do { \
157
    struct mpiio_file_record_ref *rec_ref; \
158
    int size = 0; \
Shane Snyder's avatar
Shane Snyder committed
159
    double __elapsed = __tm2-__tm1; \
160
    if(__ret != MPI_SUCCESS) break; \
161 162
    rec_ref = darshan_lookup_record_ref(mpiio_runtime->fh_hash, &(__fh), sizeof(MPI_File)); \
    if(!rec_ref) break; \
163 164
    DARSHAN_MPI_CALL(PMPI_Type_size)(__datatype, &size);  \
    size = size * __count; \
165
    /* DXT to record detailed read tracing information */ \
166 167
    if(enable_dxt_io_trace) { \
        dxt_mpiio_read(rec_ref->file_rec->base_rec.id, size, __tm1, __tm2); \
168
    } \
169 170 171 172 173 174 175 176 177
    DARSHAN_BUCKET_INC(&(rec_ref->file_rec->counters[MPIIO_SIZE_READ_AGG_0_100]), size); \
    darshan_common_val_counter(&rec_ref->access_root, &rec_ref->access_count, size, \
        &(rec_ref->file_rec->counters[MPIIO_ACCESS1_ACCESS]), \
        &(rec_ref->file_rec->counters[MPIIO_ACCESS1_COUNT])); \
    rec_ref->file_rec->counters[MPIIO_BYTES_READ] += size; \
    rec_ref->file_rec->counters[__counter] += 1; \
    if(rec_ref->last_io_type == DARSHAN_IO_WRITE) \
        rec_ref->file_rec->counters[MPIIO_RW_SWITCHES] += 1; \
    rec_ref->last_io_type = DARSHAN_IO_READ; \
178 179
    if(rec_ref->file_rec->fcounters[MPIIO_F_READ_START_TIMESTAMP] == 0 || \
     rec_ref->file_rec->fcounters[MPIIO_F_READ_START_TIMESTAMP] > __tm1) \
180 181 182 183 184 185 186
        rec_ref->file_rec->fcounters[MPIIO_F_READ_START_TIMESTAMP] = __tm1; \
    rec_ref->file_rec->fcounters[MPIIO_F_READ_END_TIMESTAMP] = __tm2; \
    if(rec_ref->file_rec->fcounters[MPIIO_F_MAX_READ_TIME] < __elapsed) { \
        rec_ref->file_rec->fcounters[MPIIO_F_MAX_READ_TIME] = __elapsed; \
        rec_ref->file_rec->counters[MPIIO_MAX_READ_TIME_SIZE] = size; } \
    DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[MPIIO_F_READ_TIME], \
        __tm1, __tm2, rec_ref->last_read_end); \
187
} while(0)
188

189
#define MPIIO_RECORD_WRITE(__ret, __fh, __count, __datatype, __counter, __tm1, __tm2) do { \
190
    struct mpiio_file_record_ref *rec_ref; \
191
    int size = 0; \
Shane Snyder's avatar
Shane Snyder committed
192 193
    double __elapsed = __tm2-__tm1; \
    if(__ret != MPI_SUCCESS) break; \
194 195
    rec_ref = darshan_lookup_record_ref(mpiio_runtime->fh_hash, &(__fh), sizeof(MPI_File)); \
    if(!rec_ref) break; \
196 197
    DARSHAN_MPI_CALL(PMPI_Type_size)(__datatype, &size);  \
    size = size * __count; \
198
     /* DXT to record detailed write tracing information */ \
199 200
    if(enable_dxt_io_trace) { \
        dxt_mpiio_write(rec_ref->file_rec->base_rec.id, size, __tm1, __tm2); \
201
    } \
202 203 204 205 206 207 208 209 210
    DARSHAN_BUCKET_INC(&(rec_ref->file_rec->counters[MPIIO_SIZE_WRITE_AGG_0_100]), size); \
    darshan_common_val_counter(&rec_ref->access_root, &rec_ref->access_count, size, \
        &(rec_ref->file_rec->counters[MPIIO_ACCESS1_ACCESS]), \
        &(rec_ref->file_rec->counters[MPIIO_ACCESS1_COUNT])); \
    rec_ref->file_rec->counters[MPIIO_BYTES_WRITTEN] += size; \
    rec_ref->file_rec->counters[__counter] += 1; \
    if(rec_ref->last_io_type == DARSHAN_IO_READ) \
        rec_ref->file_rec->counters[MPIIO_RW_SWITCHES] += 1; \
    rec_ref->last_io_type = DARSHAN_IO_WRITE; \
211
    if(rec_ref->file_rec->fcounters[MPIIO_F_WRITE_START_TIMESTAMP] == 0 || \
212
     rec_ref->file_rec->fcounters[MPIIO_F_WRITE_START_TIMESTAMP] > __tm1) \
213 214 215 216 217 218 219
        rec_ref->file_rec->fcounters[MPIIO_F_WRITE_START_TIMESTAMP] = __tm1; \
    rec_ref->file_rec->fcounters[MPIIO_F_WRITE_END_TIMESTAMP] = __tm2; \
    if(rec_ref->file_rec->fcounters[MPIIO_F_MAX_WRITE_TIME] < __elapsed) { \
        rec_ref->file_rec->fcounters[MPIIO_F_MAX_WRITE_TIME] = __elapsed; \
        rec_ref->file_rec->counters[MPIIO_MAX_WRITE_TIME_SIZE] = size; } \
    DARSHAN_TIMER_INC_NO_OVERLAP(rec_ref->file_rec->fcounters[MPIIO_F_WRITE_TIME], \
        __tm1, __tm2, rec_ref->last_write_end); \
220 221
} while(0)

222 223 224
/**********************************************************
 *        Wrappers for MPI-IO functions of interest       * 
 **********************************************************/
Philip Carns's avatar
Philip Carns committed
225

Philip Carns's avatar
Philip Carns committed
226
#ifdef HAVE_MPIIO_CONST
227 228
DARSHAN_MPI_MAP(MPI_File_open, int,  (MPI_Comm comm, const char *filename, int amode, MPI_Info info, MPI_File *fh), MPI_File_open(comm,filename,amode,info,fh)) 
int DARSHAN_MPI_DECL(MPI_File_open)(MPI_Comm comm, const char *filename, int amode, MPI_Info info, MPI_File *fh) 
Philip Carns's avatar
Philip Carns committed
229
#else
230 231
DARSHAN_MPI_MAP(MPI_File_open, int,  (MPI_Comm comm, char *filename, int amode, MPI_Info info, MPI_File *fh), MPI_File_open(comm,filename,amode,info,fh)) 
int DARSHAN_MPI_DECL(MPI_File_open)(MPI_Comm comm, char *filename, int amode, MPI_Info info, MPI_File *fh) 
Philip Carns's avatar
Philip Carns committed
232 233 234
#endif
{
    int ret;
235
    MPI_File tmp_fh;
Philip Carns's avatar
Philip Carns committed
236 237 238 239 240 241 242
    char* tmp;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_open)(comm, filename, amode, info, fh);
    tm2 = darshan_core_wtime();

243 244 245 246 247 248 249 250
    /* use ROMIO approach to strip prefix if present */
    /* strip off prefix if there is one, but only skip prefixes
     * if they are greater than length one to allow for windows
     * drive specifications (e.g. c:\...) 
     */
    tmp = strchr(filename, ':');
    if (tmp > filename + 1) {
        filename = tmp + 1;
Philip Carns's avatar
Philip Carns committed
251 252
    }

253 254 255 256 257
    MPIIO_PRE_RECORD();
    tmp_fh = *fh;
    MPIIO_RECORD_OPEN(ret, filename, tmp_fh, comm, amode, info, tm1, tm2);
    MPIIO_POST_RECORD();

Philip Carns's avatar
Philip Carns committed
258 259 260
    return(ret);
}

261 262 263 264
DARSHAN_MPI_MAP(MPI_File_read, int, (MPI_File fh, void *buf, int count,
    MPI_Datatype datatype, MPI_Status *status), MPI_File_read(fh,buf,count,datatype,status))

int DARSHAN_MPI_DECL(MPI_File_read)(MPI_File fh, void *buf, int count,
265 266 267 268 269 270 271 272 273
    MPI_Datatype datatype, MPI_Status *status)
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read)(fh, buf, count, datatype, status);
    tm2 = darshan_core_wtime();

274
    MPIIO_PRE_RECORD();
275
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_INDEP_READS, tm1, tm2);
276 277
    MPIIO_POST_RECORD();

278 279 280 281
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
282 283 284 285
DARSHAN_MPI_MAP(MPI_File_write, int, (MPI_File fh, const void *buf, int count,
    MPI_Datatype datatype, MPI_Status *status), MPI_File_write(fh,buf,count,datatype,status))

int DARSHAN_MPI_DECL(MPI_File_write)(MPI_File fh, const void *buf, int count,
286 287
    MPI_Datatype datatype, MPI_Status *status)
#else
288 289 290 291
DARSHAN_MPI_MAP(MPI_File_write, int, (MPI_File fh, void *buf, int count,
    MPI_Datatype datatype, MPI_Status *status), MPI_File_write(fh,buf,count,datatype,status))

int DARSHAN_MPI_DECL(MPI_File_write)(MPI_File fh, void *buf, int count,
292 293 294 295 296 297 298 299 300 301
    MPI_Datatype datatype, MPI_Status *status)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write)(fh, buf, count, datatype, status);
    tm2 = darshan_core_wtime();

302
    MPIIO_PRE_RECORD();
303
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_INDEP_WRITES, tm1, tm2);
304 305
    MPIIO_POST_RECORD();

306 307 308
    return(ret);
}

309 310 311 312
DARSHAN_MPI_MAP(MPI_File_read_at, int, (MPI_File fh, MPI_Offset offset, void *buf,
    int count, MPI_Datatype datatype, MPI_Status *status), MPI_File_read_at(fh, offset, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_read_at)(MPI_File fh, MPI_Offset offset, void *buf,
313 314 315 316 317 318 319 320 321 322
    int count, MPI_Datatype datatype, MPI_Status *status)
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_at)(fh, offset, buf,
        count, datatype, status);
    tm2 = darshan_core_wtime();

323
    MPIIO_PRE_RECORD();
324
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_INDEP_READS, tm1, tm2);
325 326
    MPIIO_POST_RECORD();

327 328 329 330
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
331 332 333 334
DARSHAN_MPI_MAP(MPI_File_write_at, int, (MPI_File fh, MPI_Offset offset, const void *buf,
    int count, MPI_Datatype datatype, MPI_Status *status), MPI_File_write_at(fh, offset, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_at)(MPI_File fh, MPI_Offset offset, const void *buf,
335 336
    int count, MPI_Datatype datatype, MPI_Status *status)
#else
337 338 339 340
DARSHAN_MPI_MAP(MPI_File_write_at, int, (MPI_File fh, MPI_Offset offset, void *buf,
    int count, MPI_Datatype datatype, MPI_Status *status), MPI_File_write_at(fh, offset, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_at)(MPI_File fh, MPI_Offset offset, void *buf,
341 342 343 344 345 346 347 348 349 350 351
    int count, MPI_Datatype datatype, MPI_Status *status)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_at)(fh, offset, buf,
        count, datatype, status);
    tm2 = darshan_core_wtime();

352
    MPIIO_PRE_RECORD();
353
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_INDEP_WRITES, tm1, tm2);
354 355
    MPIIO_POST_RECORD();

356 357 358
    return(ret);
}

359 360 361 362
DARSHAN_MPI_MAP(MPI_File_read_all, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status),
        MPI_File_read_all(fh,buf,count,datatype,status))

int DARSHAN_MPI_DECL(MPI_File_read_all)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status)
363 364 365 366 367 368 369 370 371
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_all)(fh, buf, count,
        datatype, status);
    tm2 = darshan_core_wtime();

372
    MPIIO_PRE_RECORD();
373
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_COLL_READS, tm1, tm2);
374 375
    MPIIO_POST_RECORD();

376 377 378 379
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
380 381 382 383
DARSHAN_MPI_MAP(MPI_File_write_all, int, (MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status *status),
        MPI_File_write_all(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_all)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status *status)
384
#else
385 386 387 388 389 390
DARSHAN_MPI_MAP(MPI_File_write_all, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status),
        MPI_File_write_all(fh, buf, count, datatype, status))
DARSHAN_MPI_MAP(PMPI_File_write_all, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status),
        MPI_File_write_all(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_all)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status)
391 392 393 394 395 396 397 398 399 400
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_all)(fh, buf, count,
        datatype, status);
    tm2 = darshan_core_wtime();

401
    MPIIO_PRE_RECORD();
402
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_COLL_WRITES, tm1, tm2);
403 404
    MPIIO_POST_RECORD();

405 406 407
    return(ret);
}

408 409 410 411 412
DARSHAN_MPI_MAP(MPI_File_read_at_all, int, (MPI_File fh, MPI_Offset offset, void * buf,
    int count, MPI_Datatype datatype, MPI_Status * status),
        MPI_File_read_at_all(fh,offset,buf,count,datatype,status))

int DARSHAN_MPI_DECL(MPI_File_read_at_all)(MPI_File fh, MPI_Offset offset, void * buf,
413 414 415 416 417 418 419 420 421 422
    int count, MPI_Datatype datatype, MPI_Status * status)
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_at_all)(fh, offset, buf,
        count, datatype, status);
    tm2 = darshan_core_wtime();

423
    MPIIO_PRE_RECORD();
424
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_COLL_READS, tm1, tm2);
425 426
    MPIIO_POST_RECORD();

427 428 429 430
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
431 432 433 434 435
DARSHAN_MPI_MAP(MPI_File_write_at_all, int, (MPI_File fh, MPI_Offset offset, const void * buf,
    int count, MPI_Datatype datatype, MPI_Status * status),
        MPI_File_write_at_all(fh, offset, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_at_all)(MPI_File fh, MPI_Offset offset, const void * buf,
436 437
    int count, MPI_Datatype datatype, MPI_Status * status)
#else
438 439 440 441 442
DARSHAN_MPI_MAP(MPI_File_write_at_all, int, (MPI_File fh, MPI_Offset offset, void * buf,
    int count, MPI_Datatype datatype, MPI_Status * status),
        MPI_File_write_at_all(fh, offset, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_at_all)(MPI_File fh, MPI_Offset offset, void * buf,
443 444 445 446 447 448 449 450 451 452 453
    int count, MPI_Datatype datatype, MPI_Status * status)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_at_all)(fh, offset, buf,
        count, datatype, status);
    tm2 = darshan_core_wtime();

454
    MPIIO_PRE_RECORD();
455
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_COLL_WRITES, tm1, tm2);
456 457
    MPIIO_POST_RECORD();

458 459 460
    return(ret);
}

461 462 463 464 465

DARSHAN_MPI_MAP(MPI_File_read_shared, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status),
        MPI_File_read_shared(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_read_shared)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status)
466 467 468 469 470 471 472 473 474
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_shared)(fh, buf, count,
        datatype, status);
    tm2 = darshan_core_wtime();

475
    MPIIO_PRE_RECORD();
476
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_INDEP_READS, tm1, tm2);
477 478
    MPIIO_POST_RECORD();

479 480 481 482
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
483 484 485 486
DARSHAN_MPI_MAP(MPI_File_write_shared, int, (MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status *status),
        MPI_File_write_shared(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_shared)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype, MPI_Status *status)
487
#else
488 489 490 491
DARSHAN_MPI_MAP(MPI_File_write_shared, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status),
        MPI_File_write_shared(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_shared)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, MPI_Status *status)
492 493 494 495 496 497 498 499 500 501
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_shared)(fh, buf, count,
        datatype, status);
    tm2 = darshan_core_wtime();

502
    MPIIO_PRE_RECORD();
503
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_INDEP_WRITES, tm1, tm2);
504 505
    MPIIO_POST_RECORD();

506 507 508
    return(ret);
}

509 510 511 512 513
DARSHAN_MPI_MAP(MPI_File_read_ordered, int, (MPI_File fh, void * buf, int count,
    MPI_Datatype datatype, MPI_Status * status),
        MPI_File_read_ordered(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_read_ordered)(MPI_File fh, void * buf, int count,
514 515 516 517 518 519 520 521 522 523
    MPI_Datatype datatype, MPI_Status * status)
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_ordered)(fh, buf, count,
        datatype, status);
    tm2 = darshan_core_wtime();

524
    MPIIO_PRE_RECORD();
525
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_COLL_READS, tm1, tm2);
526 527
    MPIIO_POST_RECORD();

528 529 530 531
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
532 533 534 535 536
DARSHAN_MPI_MAP(MPI_File_write_ordered, int, (MPI_File fh, const void * buf, int count,
    MPI_Datatype datatype, MPI_Status * status),
        MPI_File_write_ordered(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_ordered)(MPI_File fh, const void * buf, int count,
537 538
    MPI_Datatype datatype, MPI_Status * status)
#else
539 540 541 542 543
DARSHAN_MPI_MAP(MPI_File_write_ordered, int, (MPI_File fh, void * buf, int count,
    MPI_Datatype datatype, MPI_Status * status),
        MPI_File_write_ordered(fh, buf, count, datatype, status))

int DARSHAN_MPI_DECL(MPI_File_write_ordered)(MPI_File fh, void * buf, int count,
544 545 546 547 548 549 550 551 552 553 554
    MPI_Datatype datatype, MPI_Status * status)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_ordered)(fh, buf, count,
         datatype, status);
    tm2 = darshan_core_wtime();

555
    MPIIO_PRE_RECORD();
556
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_COLL_WRITES, tm1, tm2);
557 558
    MPIIO_POST_RECORD();

559 560 561
    return(ret);
}

562 563 564 565

DARSHAN_MPI_MAP(MPI_File_read_all_begin, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype),
        MPI_File_read_all_begin(fh, buf, count, datatype))
int DARSHAN_MPI_DECL(MPI_File_read_all_begin)(MPI_File fh, void * buf, int count, MPI_Datatype datatype)
566 567 568 569 570 571 572 573
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_all_begin)(fh, buf, count, datatype);
    tm2 = darshan_core_wtime();

574
    MPIIO_PRE_RECORD();
575
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_SPLIT_READS, tm1, tm2);
576 577
    MPIIO_POST_RECORD();

578 579 580 581
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
582 583 584
DARSHAN_MPI_MAP(MPI_File_write_all_begin, int, (MPI_File fh, const void * buf, int count, MPI_Datatype datatype),
        MPI_File_write_all_begin(fh, buf, count, datatype))
int DARSHAN_MPI_DECL(MPI_File_write_all_begin)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype)
585
#else
586 587 588
DARSHAN_MPI_MAP(MPI_File_write_all_begin, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype),
        MPI_File_write_all_begin(fh, buf, count, datatype))
int DARSHAN_MPI_DECL(MPI_File_write_all_begin)(MPI_File fh, void * buf, int count, MPI_Datatype datatype)
589 590 591 592 593 594 595 596 597
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_all_begin)(fh, buf, count, datatype);
    tm2 = darshan_core_wtime();

598
    MPIIO_PRE_RECORD();
599
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_SPLIT_WRITES, tm1, tm2);
600 601
    MPIIO_POST_RECORD();

602 603 604
    return(ret);
}

605 606 607 608
DARSHAN_MPI_MAP(MPI_File_read_at_all_begin, int, (MPI_File fh, MPI_Offset offset, void * buf,
    int count, MPI_Datatype datatype), MPI_File_read_at_all_begin(fh, offset, buf, count,
        datatype))
int DARSHAN_MPI_DECL(MPI_File_read_at_all_begin)(MPI_File fh, MPI_Offset offset, void * buf,
609 610 611 612 613 614 615 616 617 618
    int count, MPI_Datatype datatype)
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_at_all_begin)(fh, offset, buf,
        count, datatype);
    tm2 = darshan_core_wtime();
    
619
    MPIIO_PRE_RECORD();
620
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_SPLIT_READS, tm1, tm2);
621 622
    MPIIO_POST_RECORD();

623 624 625 626
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
627 628 629 630
DARSHAN_MPI_MAP(MPI_File_write_at_all_begin, int, (MPI_File fh, MPI_Offset offset, const void * buf,
    int count, MPI_Datatype datatype), MPI_File_write_at_all_begin( fh, offset, buf, count, datatype))

int DARSHAN_MPI_DECL(MPI_File_write_at_all_begin)(MPI_File fh, MPI_Offset offset, const void * buf,
631 632
    int count, MPI_Datatype datatype)
#else
633 634 635 636
DARSHAN_MPI_MAP(MPI_File_write_at_all_begin, int, (MPI_File fh, MPI_Offset offset, void * buf,
    int count, MPI_Datatype datatype), MPI_File_write_at_all_begin( fh, offset, buf, count, datatype))

int DARSHAN_MPI_DECL(MPI_File_write_at_all_begin)(MPI_File fh, MPI_Offset offset, void * buf,
637 638 639 640 641 642 643 644 645 646 647
    int count, MPI_Datatype datatype)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_at_all_begin)(fh, offset,
        buf, count, datatype);
    tm2 = darshan_core_wtime();

648
    MPIIO_PRE_RECORD();
649
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_SPLIT_WRITES, tm1, tm2);
650 651
    MPIIO_POST_RECORD();

652 653 654
    return(ret);
}

655 656 657 658

DARSHAN_MPI_MAP(MPI_File_read_ordered_begin, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype),
        MPI_File_read_ordered_begin(fh, buf, count, datatype))
int DARSHAN_MPI_DECL(MPI_File_read_ordered_begin)(MPI_File fh, void * buf, int count, MPI_Datatype datatype)
659 660 661 662 663 664 665 666 667
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_read_ordered_begin)(fh, buf, count,
        datatype);
    tm2 = darshan_core_wtime();

668
    MPIIO_PRE_RECORD();
669
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_SPLIT_READS, tm1, tm2);
670 671
    MPIIO_POST_RECORD();

672 673 674 675
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
676 677 678
DARSHAN_MPI_MAP(MPI_File_write_ordered_begin, int, (MPI_File fh, const void * buf, int count, MPI_Datatype datatype),
        MPI_File_write_ordered_begin(fh, buf, count, datatype))
int DARSHAN_MPI_DECL(MPI_File_write_ordered_begin)(MPI_File fh, const void * buf, int count, MPI_Datatype datatype)
679
#else
680
int DARSHAN_MPI_DECL(MPI_File_write_ordered_begin)(MPI_File fh, void * buf, int count, MPI_Datatype datatype)
681 682 683 684 685 686 687 688 689 690
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_write_ordered_begin)(fh, buf, count,
        datatype);
    tm2 = darshan_core_wtime();

691
    MPIIO_PRE_RECORD();
692
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_SPLIT_WRITES, tm1, tm2);
693 694
    MPIIO_POST_RECORD();

695 696 697
    return(ret);
}

698 699 700
DARSHAN_MPI_MAP(MPI_File_iread, int, (MPI_File fh, void * buf, int count, MPI_Datatype datatype, __D_MPI_REQUEST * request),
        MPI_File_iread(fh, buf, count, datatype, request))
int DARSHAN_MPI_DECL(MPI_File_iread)(MPI_File fh, void * buf, int count, MPI_Datatype datatype, __D_MPI_REQUEST * request)
701 702 703 704 705 706 707 708
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_iread)(fh, buf, count, datatype, request);
    tm2 = darshan_core_wtime();

709
    MPIIO_PRE_RECORD();
710
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_NB_READS, tm1, tm2);
711 712
    MPIIO_POST_RECORD();

713 714 715 716
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
717 718 719 720 721
DARSHAN_MPI_MAP(MPI_File_iwrite, int, (MPI_File fh, const void * buf, int count,
    MPI_Datatype datatype, __D_MPI_REQUEST * request),
        MPI_File_iwrite(fh, buf, count, datatype, request))

int DARSHAN_MPI_DECL(MPI_File_iwrite)(MPI_File fh, const void * buf, int count,
722 723
    MPI_Datatype datatype, __D_MPI_REQUEST * request)
#else
724 725 726 727 728
DARSHAN_MPI_MAP(MPI_File_iwrite, int, (MPI_File fh, void * buf, int count,
    MPI_Datatype datatype, __D_MPI_REQUEST * request),
        MPI_File_iwrite(fh, buf, count, datatype, request))

int DARSHAN_MPI_DECL(MPI_File_iwrite)(MPI_File fh, void * buf, int count,
729 730 731 732 733 734 735 736 737 738
    MPI_Datatype datatype, __D_MPI_REQUEST * request)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_iwrite)(fh, buf, count, datatype, request);
    tm2 = darshan_core_wtime();

739
    MPIIO_PRE_RECORD();
740
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_NB_WRITES, tm1, tm2);
741 742
    MPIIO_POST_RECORD();

743 744
    return(ret);
}
745 746 747
DARSHAN_MPI_MAP(MPI_File_iread_at, int, (MPI_File fh, MPI_Offset offset, void * buf,
    int count, MPI_Datatype datatype, __D_MPI_REQUEST *request),
        MPI_File_iread_at(fh, offset,buf,count,datatype,request))
748

749
int DARSHAN_MPI_DECL(MPI_File_iread_at)(MPI_File fh, MPI_Offset offset, void * buf,
750 751 752 753 754 755 756 757 758 759
    int count, MPI_Datatype datatype, __D_MPI_REQUEST *request)
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_iread_at)(fh, offset, buf, count,
        datatype, request);
    tm2 = darshan_core_wtime();

760
    MPIIO_PRE_RECORD();
761
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_NB_READS, tm1, tm2);
762 763
    MPIIO_POST_RECORD();

764 765 766 767
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
768 769 770 771 772
DARSHAN_MPI_MAP(MPI_File_iwrite_at, int, (MPI_File fh, MPI_Offset offset, const void * buf,
    int count, MPI_Datatype datatype, __D_MPI_REQUEST *request),
        MPI_File_iwrite_at(fh, offset, buf, count, datatype, request))

int DARSHAN_MPI_DECL(MPI_File_iwrite_at)(MPI_File fh, MPI_Offset offset, const void * buf,
773 774
    int count, MPI_Datatype datatype, __D_MPI_REQUEST *request)
#else
775 776 777 778 779
DARSHAN_MPI_MAP(MPI_File_iwrite_at, int, (MPI_File fh, MPI_Offset offset, void * buf,
    int count, MPI_Datatype datatype, __D_MPI_REQUEST *request),
        MPI_File_iwrite_at(fh, offset, buf, count, datatype, request))

int DARSHAN_MPI_DECL(MPI_File_iwrite_at)(MPI_File fh, MPI_Offset offset, void * buf,
780 781 782 783 784 785 786 787 788 789 790
    int count, MPI_Datatype datatype, __D_MPI_REQUEST *request)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_iwrite_at)(fh, offset, buf,
        count, datatype, request);
    tm2 = darshan_core_wtime();

791
    MPIIO_PRE_RECORD();
792
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_NB_WRITES, tm1, tm2);
793 794
    MPIIO_POST_RECORD();

795 796 797
    return(ret);
}

798 799 800 801 802
DARSHAN_MPI_MAP(MPI_File_iread_shared, int, (MPI_File fh, void * buf, int count,
    MPI_Datatype datatype, __D_MPI_REQUEST * request),
        MPI_File_iread_shared(fh, buf, count, datatype, request))

int DARSHAN_MPI_DECL(MPI_File_iread_shared)(MPI_File fh, void * buf, int count,
803 804 805 806 807 808 809 810 811 812
    MPI_Datatype datatype, __D_MPI_REQUEST * request)
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_iread_shared)(fh, buf, count,
        datatype, request);
    tm2 = darshan_core_wtime();

813
    MPIIO_PRE_RECORD();
814
    MPIIO_RECORD_READ(ret, fh, count, datatype, MPIIO_NB_READS, tm1, tm2);
815 816
    MPIIO_POST_RECORD();

817 818 819 820
    return(ret);
}

#ifdef HAVE_MPIIO_CONST
821 822 823 824 825
DARSHAN_MPI_MAP(MPI_File_iwrite_shared, int, (MPI_File fh, const void * buf, int count,
    MPI_Datatype datatype, __D_MPI_REQUEST * request),
        MPI_File_iwrite_shared(fh, buf, count, datatype, request))

int DARSHAN_MPI_DECL(MPI_File_iwrite_shared)(MPI_File fh, const void * buf, int count,
826 827
    MPI_Datatype datatype, __D_MPI_REQUEST * request)
#else
828 829 830 831 832
DARSHAN_MPI_MAP(MPI_File_iwrite_shared, int, (MPI_File fh, void * buf, int count,
    MPI_Datatype datatype, __D_MPI_REQUEST * request),
        MPI_File_iwrite_shared(fh, buf, count, datatype, request))

int DARSHAN_MPI_DECL(MPI_File_iwrite_shared)(MPI_File fh, void * buf, int count,
833 834 835 836 837 838 839 840 841 842 843
    MPI_Datatype datatype, __D_MPI_REQUEST * request)
#endif
{
    int ret;
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_iwrite_shared)(fh, buf, count,
        datatype, request);
    tm2 = darshan_core_wtime();

844
    MPIIO_PRE_RECORD();
845
    MPIIO_RECORD_WRITE(ret, fh, count, datatype, MPIIO_NB_WRITES, tm1, tm2);
846 847
    MPIIO_POST_RECORD();

848 849
    return(ret);
}
850

851 852 853
DARSHAN_MPI_MAP(MPI_File_sync, int, (MPI_File fh), MPI_File_sync(fh))

int DARSHAN_MPI_DECL(MPI_File_sync)(MPI_File fh)
854 855
{
    int ret;
856
    struct mpiio_file_record_ref *rec_ref;
857 858 859 860 861 862 863 864
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_sync)(fh);
    tm2 = darshan_core_wtime();

    if(ret == MPI_SUCCESS)
    {
865 866 867 868
        MPIIO_PRE_RECORD();
        rec_ref = darshan_lookup_record_ref(mpiio_runtime->fh_hash,
            &fh, sizeof(MPI_File));
        if(rec_ref)
869
        {
870
            rec_ref->file_rec->counters[MPIIO_SYNCS] += 1;
871
            DARSHAN_TIMER_INC_NO_OVERLAP(
872 873
                rec_ref->file_rec->fcounters[MPIIO_F_WRITE_TIME],
                tm1, tm2, rec_ref->last_write_end);
874
        }
875
        MPIIO_POST_RECORD();
876 877 878 879 880 881
    }

    return(ret);
}

#ifdef HAVE_MPIIO_CONST
882 883 884 885
DARSHAN_MPI_MAP(MPI_File_set_view, int, (MPI_File fh, MPI_Offset disp, MPI_Datatype etype,
    MPI_Datatype filetype, const char *datarep, MPI_Info info), MPI_File_set_view(fh, disp, etype, filetype, datarep, info))

int DARSHAN_MPI_DECL(MPI_File_set_view)(MPI_File fh, MPI_Offset disp, MPI_Datatype etype,
886 887
    MPI_Datatype filetype, const char *datarep, MPI_Info info)
#else
888 889 890 891
DARSHAN_MPI_MAP(MPI_File_set_view, int, (MPI_File fh, MPI_Offset disp, MPI_Datatype etype,
    MPI_Datatype filetype, char *datarep, MPI_Info info), MPI_File_set_view(fh, disp, etype, filetype, datarep, info))

int DARSHAN_MPI_DECL(MPI_File_set_view)(MPI_File fh, MPI_Offset disp, MPI_Datatype etype,
892 893 894 895
    MPI_Datatype filetype, char *datarep, MPI_Info info)
#endif
{
    int ret;
896
    struct mpiio_file_record_ref *rec_ref;
897 898 899 900 901 902 903 904 905
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_set_view)(fh, disp, etype, filetype,
        datarep, info);
    tm2 = darshan_core_wtime();

    if(ret == MPI_SUCCESS)
    {
906 907 908 909
        MPIIO_PRE_RECORD();
        rec_ref = darshan_lookup_record_ref(mpiio_runtime->fh_hash,
            &fh, sizeof(MPI_File));
        if(rec_ref)
910
        {
911
            rec_ref->file_rec->counters[MPIIO_VIEWS] += 1;
912 913
            if(info != MPI_INFO_NULL)
            {
914
                rec_ref->file_rec->counters[MPIIO_HINTS] += 1;
915
                DARSHAN_TIMER_INC_NO_OVERLAP(
916 917
                    rec_ref->file_rec->fcounters[MPIIO_F_META_TIME],
                    tm1, tm2, rec_ref->last_meta_end);
918 919
           }
        }
920
        MPIIO_POST_RECORD();
921 922 923 924 925
    }

    return(ret);
}

926 927
DARSHAN_MPI_MAP(MPI_File_close, int, (MPI_File *fh), MPI_File_close(fh))
int DARSHAN_MPI_DECL(MPI_File_close)(MPI_File *fh)
928 929
{
    int ret;
930
    struct mpiio_file_record_ref *rec_ref;
931
    MPI_File tmp_fh = *fh;
932 933 934 935 936 937
    double tm1, tm2;

    tm1 = darshan_core_wtime();
    ret = DARSHAN_MPI_CALL(PMPI_File_close)(fh);
    tm2 = darshan_core_wtime();

938 939 940 941
    MPIIO_PRE_RECORD();
    rec_ref = darshan_lookup_record_ref(mpiio_runtime->fh_hash,
        &tmp_fh, sizeof(MPI_File));
    if(rec_ref)
942
    {
943
        rec_ref->file_rec->fcounters[MPIIO_F_CLOSE_TIMESTAMP] =
944 945
            darshan_core_wtime();
        DARSHAN_TIMER_INC_NO_OVERLAP(
946 947 948 949
            rec_ref->file_rec->fcounters[MPIIO_F_META_TIME],
            tm1, tm2, rec_ref->last_meta_end);
        darshan_delete_record_ref(&(mpiio_runtime->fh_hash),
            &tmp_fh, sizeof(MPI_File));
950
    }
951
    MPIIO_POST_RECORD();
952 953 954 955 956 957 958 959 960

    return(ret);
}

/***********************************************************
 * Internal functions for manipulating MPI-IO module state *
 ***********************************************************/

/* initialize data structures and register with darshan-core component */
Philip Carns's avatar
Philip Carns committed
961 962
static void mpiio_runtime_initialize()
{
963
    int mpiio_buf_size;
Philip Carns's avatar
Philip Carns committed
964

965 966 967
    /* try and store the default number of records for this module */
    mpiio_buf_size = DARSHAN_DEF_MOD_REC_COUNT * sizeof(struct darshan_mpiio_file);

Philip Carns's avatar
Philip Carns committed
968 969 970
    /* register the mpiio module with darshan core */
    darshan_core_register_module(
        DARSHAN_MPIIO_MOD,
971
        &mpiio_shutdown,
972
        &mpiio_buf_size,
973
        &my_rank,
974
        NULL);
Philip Carns's avatar
Philip Carns committed
975

976 977
    /* return if darshan-core does not provide enough module memory */
    if(mpiio_buf_size < sizeof(struct darshan_mpiio_file))
978 979
    {
        darshan_core_unregister_module(DARSHAN_MPIIO_MOD);
Philip Carns's avatar
Philip Carns committed
980
        return;
981
    }
Philip Carns's avatar
Philip Carns committed
982 983 984

    mpiio_runtime = malloc(sizeof(*mpiio_runtime));
    if(!mpiio_runtime)
985 986
    {
        darshan_core_unregister_module(DARSHAN_MPIIO_MOD);
Philip Carns's avatar
Philip Carns committed
987
        return;
988
    }
Philip Carns's avatar
Philip Carns committed
989 990
    memset(mpiio_runtime, 0, sizeof(*mpiio_runtime));

991
    /* check if DXT (Darshan extended tracing) should be enabled */
992
    if (getenv("DXT_ENABLE_IO_TRACE")) {
993 994 995
        enable_dxt_io_trace = 1;
    }

Philip Carns's avatar
Philip Carns committed
996 997 998
    return;
}

999 1000
static struct mpiio_file_record_ref *mpiio_track_new_file_record(
    darshan_record_id rec_id, const char *path)
1001
{
1002 1003
    struct darshan_mpiio_file *file_rec = NULL;
    struct mpiio_file_record_ref *rec_ref = NULL;
1004
    int ret;
1005

1006 1007
    rec_ref = malloc(sizeof(*rec_ref));
    if(!rec_ref)
1008
        return(NULL);