darshan-null-logutils.c 9.92 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 2015 University of Chicago.
 * See COPYRIGHT notice in top-level directory.
 *
 */

#define _GNU_SOURCE
#include "darshan-util-config.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

20
#include "darshan-logutils.h"
21
22
23
24
25
26
27
28
29
30
31
32
33
34

/* integer counter name strings for the NULL module */
#define X(a) #a,
char *null_counter_names[] = {
    NULL_COUNTERS
};

/* floating point counter name strings for the NULL module */
char *null_f_counter_names[] = {
    NULL_F_COUNTERS
};
#undef X

/* prototypes for each of the NULL module's logutil functions */
35
static int darshan_log_get_null_record(darshan_fd fd, void** null_buf_p);
36
static int darshan_log_put_null_record(darshan_fd fd, void* null_buf);
37
static void darshan_log_print_null_record(void *file_rec,
38
    char *file_name, char *mnt_pt, char *fs_type);
39
static void darshan_log_print_null_description(int ver);
40
41
static void darshan_log_print_null_record_diff(void *file_rec1, char *file_name1,
    void *file_rec2, char *file_name2);
42
static void darshan_log_agg_null_records(void *rec, void *agg_rec, int init_flag);
43
44
45
46
47
48
49
50
51
52

/* structure storing each function needed for implementing the darshan
 * logutil interface. these functions are used for reading, writing, and
 * printing module data in a consistent manner.
 */
struct darshan_mod_logutil_funcs null_logutils =
{
    .log_get_record = &darshan_log_get_null_record,
    .log_put_record = &darshan_log_put_null_record,
    .log_print_record = &darshan_log_print_null_record,
53
    .log_print_description = &darshan_log_print_null_description,
54
    .log_print_diff = &darshan_log_print_null_record_diff,
55
    .log_agg_records = &darshan_log_agg_null_records
56
57
58
};

/* retrieve a NULL record from log file descriptor 'fd', storing the
59
60
 * data in the buffer address pointed to by 'null_buf_p'. Return 1 on
 * successful record read, 0 on no more data, and -1 on error.
61
 */
62
static int darshan_log_get_null_record(darshan_fd fd, void** null_buf_p)
63
{
64
    struct darshan_null_record *rec = *((struct darshan_null_record **)null_buf_p);
65
66
67
    int i;
    int ret;

68
69
70
71
72
73
74
75
76
77
    if(fd->mod_map[DARSHAN_NULL_MOD].len == 0)
        return(0);

    if(*null_buf_p == NULL)
    {
        rec = malloc(sizeof(*rec));
        if(!rec)
            return(-1);
    }

78
    /* read a NULL module record from the darshan log file */
79
    ret = darshan_log_get_mod(fd, DARSHAN_NULL_MOD, rec,
80
        sizeof(struct darshan_null_record));
81
82
83
84
85
86
87
88
89

    if(*null_buf_p == NULL)
    {
        if(ret == sizeof(struct darshan_null_record))
            *null_buf_p = rec;
        else
            free(rec);
    }

90
91
92
93
94
95
96
97
98
    if(ret < 0)
        return(-1);
    else if(ret < sizeof(struct darshan_null_record))
        return(0);
    else
    {
        /* if the read was successful, do any necessary byte-swapping */
        if(fd->swap_flag)
        {
99
100
            DARSHAN_BSWAP64(&(rec->base_rec.id));
            DARSHAN_BSWAP64(&(rec->base_rec.rank));
101
102
103
104
105
106
107
108
109
110
            for(i=0; i<NULL_NUM_INDICES; i++)
                DARSHAN_BSWAP64(&rec->counters[i]);
            for(i=0; i<NULL_F_NUM_INDICES; i++)
                DARSHAN_BSWAP64(&rec->fcounters[i]);
        }

        return(1);
    }
}

111
112
/* write the NULL record stored in 'null_buf' to log file descriptor 'fd'.
 * Return 0 on success, -1 on failure
113
 */
114
static int darshan_log_put_null_record(darshan_fd fd, void* null_buf)
115
116
117
118
119
{
    struct darshan_null_record *rec = (struct darshan_null_record *)null_buf;
    int ret;

    /* append NULL record to darshan log file */
120
    ret = darshan_log_put_mod(fd, DARSHAN_NULL_MOD, rec,
121
        sizeof(struct darshan_null_record), DARSHAN_NULL_VER);
122
123
124
125
126
127
128
129
    if(ret < 0)
        return(-1);

    return(0);
}

/* print all I/O data record statistics for the given NULL record */
static void darshan_log_print_null_record(void *file_rec, char *file_name,
130
    char *mnt_pt, char *fs_type)
131
132
133
134
135
136
137
138
139
140
{
    int i;
    struct darshan_null_record *null_rec =
        (struct darshan_null_record *)file_rec;

    /* print each of the integer and floating point counters for the NULL module */
    for(i=0; i<NULL_NUM_INDICES; i++)
    {
        /* macro defined in darshan-logutils.h */
        DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
141
142
143
            null_rec->base_rec.rank, null_rec->base_rec.id,
            null_counter_names[i], null_rec->counters[i],
            file_name, mnt_pt, fs_type);
144
145
146
147
148
149
    }

    for(i=0; i<NULL_F_NUM_INDICES; i++)
    {
        /* macro defined in darshan-logutils.h */
        DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
150
151
152
            null_rec->base_rec.rank, null_rec->base_rec.id,
            null_f_counter_names[i], null_rec->fcounters[i],
            file_name, mnt_pt, fs_type);
153
154
155
156
157
    }

    return;
}

158
/* print out a description of the NULL module record fields */
159
static void darshan_log_print_null_description(int ver)
160
{
161
    printf("\n# description of NULL counters:\n");
162
163
164
165
    printf("#   NULL_FOOS: number of 'foo' function calls.\n");
    printf("#   NULL_FOO_MAX_DAT: maximum data value set by calls to 'foo'.\n");
    printf("#   NULL_F_FOO_TIMESTAMP: timestamp of the first call to function 'foo'.\n");
    printf("#   NULL_F_FOO_MAX_DURATION: timer indicating duration of call to 'foo' with max NULL_FOO_MAX_DAT value.\n");
166
167
168
169

    return;
}

170
/* print a diff of two NULL records (with the same record id) */
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
static void darshan_log_print_null_record_diff(void *file_rec1, char *file_name1,
    void *file_rec2, char *file_name2)
{
    struct darshan_null_record *file1 = (struct darshan_null_record *)file_rec1;
    struct darshan_null_record *file2 = (struct darshan_null_record *)file_rec2;
    int i;

    /* NOTE: we assume that both input records are the same module format version */

    for(i=0; i<NULL_NUM_INDICES; i++)
    {
        if(!file2)
        {
            printf("- ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
186
                file1->base_rec.rank, file1->base_rec.id, null_counter_names[i],
187
188
189
190
191
192
193
                file1->counters[i], file_name1, "", "");

        }
        else if(!file1)
        {
            printf("+ ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
194
                file2->base_rec.rank, file2->base_rec.id, null_counter_names[i],
195
196
197
198
199
200
                file2->counters[i], file_name2, "", "");
        }
        else if(file1->counters[i] != file2->counters[i])
        {
            printf("- ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
201
                file1->base_rec.rank, file1->base_rec.id, null_counter_names[i],
202
203
204
                file1->counters[i], file_name1, "", "");
            printf("+ ");
            DARSHAN_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
205
                file2->base_rec.rank, file2->base_rec.id, null_counter_names[i],
206
207
208
209
210
211
212
213
214
215
                file2->counters[i], file_name2, "", "");
        }
    }

    for(i=0; i<NULL_F_NUM_INDICES; i++)
    {
        if(!file2)
        {
            printf("- ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
216
                file1->base_rec.rank, file1->base_rec.id, null_f_counter_names[i],
217
218
219
220
221
222
223
                file1->fcounters[i], file_name1, "", "");

        }
        else if(!file1)
        {
            printf("+ ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
224
                file2->base_rec.rank, file2->base_rec.id, null_f_counter_names[i],
225
226
227
228
229
230
                file2->fcounters[i], file_name2, "", "");
        }
        else if(file1->fcounters[i] != file2->fcounters[i])
        {
            printf("- ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
231
                file1->base_rec.rank, file1->base_rec.id, null_f_counter_names[i],
232
233
234
                file1->fcounters[i], file_name1, "", "");
            printf("+ ");
            DARSHAN_F_COUNTER_PRINT(darshan_module_names[DARSHAN_NULL_MOD],
Shane Snyder's avatar
Shane Snyder committed
235
                file2->base_rec.rank, file2->base_rec.id, null_f_counter_names[i],
236
237
238
                file2->fcounters[i], file_name2, "", "");
        }
    }
239
240
241
242

    return;
}

243
/* aggregate the input NULL record 'rec'  into the output record 'agg_rec' */
244
245
static void darshan_log_agg_null_records(void *rec, void *agg_rec, int init_flag)
{
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
    struct darshan_null_record *null_rec = (struct darshan_null_record *)rec;
    struct darshan_null_record *agg_null_rec = (struct darshan_null_record *)agg_rec;
    int i;

    for(i = 0; i < NULL_NUM_INDICES; i++)
    {
        switch(i)
        {
            case NULL_FOOS:
                /* sum */
                agg_null_rec->counters[i] += null_rec->counters[i];
                break;
            case NULL_FOO_MAX_DAT:
                /* max */
                if(null_rec->counters[i] > agg_null_rec->counters[i])
                {
                    agg_null_rec->counters[i] = null_rec->counters[i];
                    agg_null_rec->fcounters[NULL_F_FOO_MAX_DURATION] =
                        null_rec->fcounters[NULL_F_FOO_MAX_DURATION];
                }
                break;
            default:
                /* if we don't know how to aggregate this counter, just set to -1 */
                agg_null_rec->counters[i] = -1;
                break;
        }
    }

    for(i = 0; i < NULL_F_NUM_INDICES; i++)
    {
        switch(i)
        {
            case NULL_F_FOO_TIMESTAMP:
                /* min non-zero */
                if((null_rec->fcounters[i] > 0)  &&
                    ((agg_null_rec->fcounters[i] == 0) ||
                    (null_rec->fcounters[i] < agg_null_rec->fcounters[i])))
                {
                    agg_null_rec->fcounters[i] = null_rec->fcounters[i];
                }
                break;
            default:
                /* if we don't know how to aggregate this counter, just set to -1 */
                agg_null_rec->fcounters[i] = -1;
                break;
        }
    }

294
295
    return;
}
296

297
298
299
300
301
302
303
304
/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 * End:
 *
 * vim: ts=8 sts=4 sw=4 expandtab
 */