darshan-pnetcdf.c 4.83 KB
Newer Older
1 2 3 4 5
/*
 *  (C) 2009 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

6
#include "darshan-runtime-config.h"
7 8 9 10 11 12
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include "mpi.h"
#include "darshan.h"

13
#ifdef DARSHAN_PRELOAD
14 15 16 17
#define __USE_GNU
#include <dlfcn.h>
#include <stdlib.h>

18 19 20 21 22
#define DARSHAN_FORWARD_DECL(name,ret,args) \
  ret (*__real_ ## name)args = NULL;
         
#define DARSHAN_DECL(__name) __name

23 24 25 26 27 28 29 30 31 32
#define MAP_OR_FAIL(func) \
    if (!(__real_ ## func)) \
    { \
        __real_ ## func = dlsym(RTLD_NEXT, #func); \
        if(!(__real_ ## func)) { \
            fprintf(stderr, "Darshan failed to map symbol: %s\n", #func); \
            exit(1); \
        } \
    }
 
33 34 35 36 37 38 39
#else   
    
#define DARSHAN_FORWARD_DECL(name,ret,args) \
  extern ret __real_ ## name args;

#define DARSHAN_DECL(__name) __wrap_ ## __name

40 41
#define MAP_OR_FAIL(func)

42 43 44 45 46 47
#endif

DARSHAN_FORWARD_DECL(ncmpi_create, int, (MPI_Comm comm, const char *path, int cmode, MPI_Info info, int *ncidp));
DARSHAN_FORWARD_DECL(ncmpi_open, int, (MPI_Comm comm, const char *path, int omode, MPI_Info info, int *ncidp));
DARSHAN_FORWARD_DECL(ncmpi_close, int, (int ncid));

48
static struct darshan_file_runtime* darshan_file_by_ncid(int ncid);
49 50
static void darshan_file_close_ncid(int ncid);
static struct darshan_file_runtime* darshan_file_by_name_setncid(const char* name, int ncid);
51

52
int DARSHAN_DECL(ncmpi_create)(MPI_Comm comm, const char *path, 
53 54 55 56 57 58 59
    int cmode, MPI_Info info, int *ncidp)
{
    int ret;
    struct darshan_file_runtime* file;
    char* tmp;
    int comm_size;

60 61
    MAP_OR_FAIL(ncmpi_create);

62 63 64 65 66 67 68 69 70 71 72 73 74 75
    ret = __real_ncmpi_create(comm, path, cmode, info, ncidp);
    if(ret == 0)
    {  
        CP_LOCK();
        /* 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(path, ':');
        if (tmp > path + 1) {
            path = tmp + 1;
        }

76 77
        file = darshan_file_by_name_setncid(path, (*ncidp));
        if(file)
78
        {
79 80 81
            if(CP_F_VALUE(file, CP_F_OPEN_TIMESTAMP) == 0)
                CP_F_SET(file, CP_F_OPEN_TIMESTAMP,
                PMPI_Wtime());
82 83 84 85 86 87 88 89 90
            PMPI_Comm_size(comm, &comm_size);
            if(comm_size == 1)
            {
                CP_INC(file, CP_INDEP_NC_OPENS, 1);
            }
            else
            {
                CP_INC(file, CP_COLL_NC_OPENS, 1);
            }
91 92 93 94 95 96 97
        }
        CP_UNLOCK();
    }

    return(ret);
}

98
int DARSHAN_DECL(ncmpi_open)(MPI_Comm comm, const char *path, 
99 100 101 102 103 104 105
    int omode, MPI_Info info, int *ncidp)
{
    int ret;
    struct darshan_file_runtime* file;
    char* tmp;
    int comm_size;

106 107
    MAP_OR_FAIL(ncmpi_open);

108 109 110 111 112 113 114 115 116 117 118 119 120 121
    ret = __real_ncmpi_open(comm, path, omode, info, ncidp);
    if(ret == 0)
    {  
        CP_LOCK();
        /* 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(path, ':');
        if (tmp > path + 1) {
            path = tmp + 1;
        }

122 123
        file = darshan_file_by_name_setncid(path, (*ncidp));
        if(file)
124
        {
125 126 127
            if(CP_F_VALUE(file, CP_F_OPEN_TIMESTAMP) == 0)
                CP_F_SET(file, CP_F_OPEN_TIMESTAMP,
                PMPI_Wtime());
128 129 130 131 132 133 134 135 136
            PMPI_Comm_size(comm, &comm_size);
            if(comm_size == 1)
            {
                CP_INC(file, CP_INDEP_NC_OPENS, 1);
            }
            else
            {
                CP_INC(file, CP_COLL_NC_OPENS, 1);
            }
137 138 139 140 141 142 143 144
        }
        CP_UNLOCK();
    }

    return(ret);

}

145
int DARSHAN_DECL(ncmpi_close)(int ncid)
146 147 148 149
{
    struct darshan_file_runtime* file;
    int ret;

150 151
    MAP_OR_FAIL(ncmpi_close); 

152 153 154 155 156 157
    ret = __real_ncmpi_close(ncid);

    CP_LOCK();
    file = darshan_file_by_ncid(ncid);
    if(file)
    {
158
        CP_F_SET(file, CP_F_CLOSE_TIMESTAMP, PMPI_Wtime());
159
        darshan_file_close_ncid(ncid);
160 161 162 163 164 165
    }
    CP_UNLOCK();

    return(ret);
}

166
static struct darshan_file_runtime* darshan_file_by_name_setncid(const char* name, int ncid)
167 168 169
{
    struct darshan_file_runtime* tmp_file;

170 171 172
    tmp_file = darshan_file_by_name_sethandle(name, &ncid, sizeof(ncid), DARSHAN_NCID);
    return(tmp_file);
}
173

174 175 176 177 178
static void darshan_file_close_ncid(int ncid)
{
    darshan_file_closehandle(&ncid, sizeof(ncid), DARSHAN_NCID);
    return;
}
179

180 181 182
static struct darshan_file_runtime* darshan_file_by_ncid(int ncid)
{
    struct darshan_file_runtime* tmp_file;
183

184 185 186
    tmp_file = darshan_file_by_handle(&ncid, sizeof(ncid), DARSHAN_NCID);
    
    return(tmp_file);
187 188 189
}


190

191 192 193 194 195 196 197 198
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */