~ubuntu-branches/ubuntu/utopic/nwchem/utopic

« back to all changes in this revision

Viewing changes to src/tools/ga-5-2/tcgmsg/tcgmsg-mpi/evlog.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Daniel Leidert, Andreas Tille, Michael Banck
  • Date: 2013-07-04 12:14:55 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130704121455-5tvsx2qabor3nrui
Tags: 6.3-1
* New upstream release.
* Fixes anisotropic properties (Closes: #696361).
* New features include:
  + Multi-reference coupled cluster (MRCC) approaches
  + Hybrid DFT calculations with short-range HF 
  + New density-functionals including Minnesota (M08, M11) and HSE hybrid
    functionals
  + X-ray absorption spectroscopy (XAS) with TDDFT
  + Analytical gradients for the COSMO solvation model
  + Transition densities from TDDFT 
  + DFT+U and Electron-Transfer (ET) methods for plane wave calculations
  + Exploitation of space group symmetry in plane wave geometry optimizations
  + Local density of states (LDOS) collective variable added to Metadynamics
  + Various new XC functionals added for plane wave calculations, including
    hybrid and range-corrected ones
  + Electric field gradients with relativistic corrections 
  + Nudged Elastic Band optimization method
  + Updated basis sets and ECPs 

[ Daniel Leidert ]
* debian/watch: Fixed.

[ Andreas Tille ]
* debian/upstream: References

[ Michael Banck ]
* debian/upstream (Name): New field.
* debian/patches/02_makefile_flags.patch: Refreshed.
* debian/patches/06_statfs_kfreebsd.patch: Likewise.
* debian/patches/07_ga_target_force_linux.patch: Likewise.
* debian/patches/05_avoid_inline_assembler.patch: Removed, no longer needed.
* debian/patches/09_backported_6.1.1_fixes.patch: Likewise.
* debian/control (Build-Depends): Added gfortran-4.7 and gcc-4.7.
* debian/patches/10_force_gcc-4.7.patch: New patch, explicitly sets
  gfortran-4.7 and gcc-4.7, fixes test suite hang with gcc-4.8 (Closes:
  #701328, #713262).
* debian/testsuite: Added tests for COSMO analytical gradients and MRCC.
* debian/rules (MRCC_METHODS): New variable, required to enable MRCC methods.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if HAVE_CONFIG_H
 
2
#   include "config.h"
 
3
#endif
 
4
 
 
5
/**
 
6
 * Event logging routine with key driven varargs interface
 
7
 */
 
8
 
 
9
#include <stdio.h>
 
10
#include <stdarg.h>
 
11
#include <strings.h>
 
12
#include <string.h>
 
13
#include <stdlib.h>
 
14
 
 
15
#include "evlog.h"
 
16
#include "sndrcv.h"
 
17
 
 
18
#define  BUFLEN 262144     /**< Size allocated for buffer ... biggish */
 
19
#define  MAX_EV_LEN 1000   /**< Assumed maximum size of single event record */
 
20
 
 
21
#define ERROR_RETURN() \
 
22
do { \
 
23
    error = 1; \
 
24
    return; \
 
25
} while (0)
 
26
 
 
27
#define DUMPBUF() \
 
28
do { \
 
29
    (void) fputs(buffer, file); \
 
30
    (void) fflush(file); \
 
31
    if (ferror(file)) { \
 
32
        ERROR_RETURN(); \
 
33
    } \
 
34
    bufpt = buffer; \
 
35
    left = BUFLEN; \
 
36
} while (0)
 
37
 
 
38
#define RECORD(A) \
 
39
do { \
 
40
    A; \
 
41
    nchars = strlen(bufpt); \
 
42
    bufpt += nchars; \
 
43
    left -= nchars; \
 
44
} while (0)
 
45
 
 
46
static double walltime();
 
47
 
 
48
/**
 
49
 * The format of the argument list is as follows:
 
50
 *
 
51
 * evlog([(int) key, [values, ...]], ..., EVKEY_LAST_ARG)
 
52
 *
 
53
 * Arguments are read as keys with corresponding values. Recognised keys
 
54
 * are defined in evlog.h and are described in detail below.
 
55
 *
 
56
 * Logging is enabled/disabled by calling evlog with one of EVKEY_ENABLE
 
57
 * or EVKEY_DISABLE specified. Note that EVKEY_ENABLE must be the
 
58
 * first key specified for it to be recognized and that all keys
 
59
 * in the argument list after EVKEY_DISABLE are ignored. By default
 
60
 * events are logged in the file events. This can be overridden with
 
61
 * the key EVKEY_FILENAME, which takes the filename as its value.
 
62
 *
 
63
 * The model for logging events assumed by the post-analysis routines
 
64
 * assumes that upon logging an event:
 
65
 *
 
66
 *   a) no state chage occurs (EVKEY_EVENT). The event is just recorded.
 
67
 *
 
68
 *   b) the process changes state by pushing the event onto the state stack
 
69
 *      (EVKEY_BEGIN).
 
70
 *
 
71
 *   c) the process changes state by popping an event off the state stack
 
72
 *      (EVKEY_END). If the event or state popped off the stack does not
 
73
 *      match the specified event then the post-analysis may get confused
 
74
 *      but this does not interfere with the actual logging.
 
75
 *
 
76
 * EVKEY_EVENT, EVKEY_BEGIN or EVKEY_END must be the first key specified other
 
77
 * than a possible EVKEY_ENABLE.
 
78
 *
 
79
 * Internally an event is stored as a large character string to simplify
 
80
 * post-analysis. Users specify data for storage in addition to
 
81
 * that which is automatically stored (only the time and process) with
 
82
 * key, value combinations (EVKEY_STR_INT, EVKEY_STR_DBL, EVKEY_STR).
 
83
 * Many such key-value combinations as required may be specified.
 
84
 * Since the internal data format uses colons ':', double quotation
 
85
 * marks '"' and carriage returns users should avoid these in their
 
86
 * string data.
 
87
 *
 
88
 * ----------------------------
 
89
 * Sample calling sequence:
 
90
 *
 
91
 * evlog(EVKEY_ENABLE, EVKEY_FILENAME, "events.log", EVKEY_LAST_ARG);
 
92
 *
 
93
 *
 
94
 *    evlog(EVKEY_EVENT, "Finished startup code",
 
95
 *          EVKEY_STR, "Now do some real work",
 
96
 *      EVKEY_LAST_ARG);
 
97
 *
 
98
 *    evlog(EVKEY_BEGIN, "Get Matrix", EVKEY_LAST_ARG);
 
99
 *
 
100
 *
 
101
 *    evlog(EVKEY_END, "Get matrix",
 
102
 *          EVKEY_STR_INT, "Size of matrix", (int) N,
 
103
 *          EVKEY_STR_DBL, "Norm of matrix", (double) matrix_norm,
 
104
 *          EVKEY_LAST_ARG);
 
105
 *
 
106
 *    evlog(EVKEY_BEGIN, "Transform matrix",
 
107
 *          EVKEY_STR_DBL, "Recomputed norm", (double) matrix_norm,
 
108
 *      EVKEY_LAST_ARG);
 
109
 *      
 
110
 *
 
111
 *    evlog(EVKEY_END, "Transform matrix",
 
112
 *          EVKEY_STR_INT, "No. of iterations", (int) niters,
 
113
 *      EVKEY_LAST_ARG);
 
114
 *
 
115
 * evlog(EVKEY_DUMP, EVKEY_DISABLE, EVKEY_LAST_ARG);
 
116
 *
 
117
 * evlog(EVKEY_EVENT, "Logging is disabled ... this should not print",
 
118
 *   EVKEY_DUMP, EVKEY_LAST_ARG);
 
119
 *
 
120
 * ----------------------------
 
121
 *
 
122
 * EVKEY_LAST_ARG
 
123
 *     Terminates list ... takes no value and must be present
 
124
 *
 
125
 * EVKEY_EVENT, (char *) event
 
126
 *     Simply log occurence of the event
 
127
 *
 
128
 * EVKEY_BEGIN, (char *) event
 
129
 *     Push event onto process state stack
 
130
 *
 
131
 * EVKEY_END, (char *) event
 
132
 *     Pop event off process state stack
 
133
 *
 
134
 * EVKEY_MSG_LEN, (int) length
 
135
 *     Value is (int) mesage length SND/RCV only
 
136
 *
 
137
 * EVKEY_MSG_TO, (int) to
 
138
 *     Value is (int) to process id SND/RCV only
 
139
 *
 
140
 * EVKEY_MSG_FROM, (int) from
 
141
 *     Value is (int) from process  SND/RCV only
 
142
 *
 
143
 * EVKEY_MSG_TYPE, (int) type
 
144
 *     Value is (int) message type  SND/RCV only
 
145
 *
 
146
 * EVKEY_STR_INT, (char *) string, (int) data
 
147
 *     User data value pair
 
148
 *
 
149
 * EVKEY_STR_DBL, (char *) string, (double) data
 
150
 *     User data value pair (char *), (double)
 
151
 *
 
152
 * EVKEY_STR, (char *) string
 
153
 *     User data value (char *)
 
154
 *
 
155
 * EVKEY_ENABLE
 
156
 *     Enable logging
 
157
 *
 
158
 * EVKEY_DISABLE
 
159
 *     Disable logging
 
160
 *
 
161
 * EVKEY_DUMP
 
162
 *     Dump out the current buffer to disk
 
163
 *
 
164
 * EVKEY_FILE, (char *) filename
 
165
 *     Use specified file to capture events. Default is "events".
 
166
 */
 
167
void evlog(int farg_key, ...)
 
168
{
 
169
    static int   logging=0;/**< Boolean flag for login enabled/disabled */
 
170
    static int   error=0;  /**< Boolean flag for error detected         */
 
171
    static int   ncall=0;  /**< Need to do stuff on first entry         */
 
172
    static char *buffer;   /**< Logging buffer ... null terminated      */
 
173
    static char *bufpt;    /**< Pointer to next free char in buffer     */
 
174
    static int   left;     /**< Amount of free space in buffer          */
 
175
    static FILE *file;     /**< File where events will be dumped */
 
176
    static char *filename = "events"; /**< Default name of events file */
 
177
 
 
178
    va_list  ap;      /**< For variable argument list */
 
179
    int      key;     /**< Hold key being processed   */
 
180
    int      nchars;  /**< No. of chars printed by sprintf call */
 
181
    char    *temp;    /**< Temporary copy of bufpt */
 
182
    char    *string;  /**< Temporary */
 
183
    int      integer; /**< Temporary */
 
184
    double   dbl;     /**< Temporary */
 
185
    int      valid;   /**< Temporary */
 
186
 
 
187
    /* If an error was detected on a previous call don't even try to
 
188
       do anything */
 
189
 
 
190
    if (error) {
 
191
        ERROR_RETURN();
 
192
    }
 
193
 
 
194
    /* First time in need to allocate the buffer, open the file etc */
 
195
 
 
196
    if (ncall == 0) {
 
197
        ncall = 1;
 
198
        if (!(bufpt = buffer = malloc((unsigned) BUFLEN))) {
 
199
            ERROR_RETURN();
 
200
        }
 
201
        left = BUFLEN;
 
202
 
 
203
        if (!(file = fopen(filename, "w"))) {
 
204
            ERROR_RETURN();
 
205
        }
 
206
    }
 
207
 
 
208
    /* Parse the arguments */
 
209
 
 
210
    temp = bufpt; /**< Save to check if anything has been logged */
 
211
    valid = 0;    /**< One of BEGIN, END or EVENT must preceed most keys */
 
212
 
 
213
    va_start(ap, farg_key);
 
214
    key = farg_key;
 
215
    while (key != EVKEY_LAST_ARG) {
 
216
 
 
217
        if ( (!logging) && (key != EVKEY_ENABLE) ) {
 
218
            return;
 
219
        }
 
220
 
 
221
        switch (key) {
 
222
 
 
223
            case EVKEY_ENABLE:
 
224
                logging = 1;
 
225
                break;
 
226
 
 
227
            case EVKEY_DISABLE:
 
228
                logging = 0;
 
229
                goto done;
 
230
                /* break; */
 
231
 
 
232
            case EVKEY_FILENAME:
 
233
                if (!(filename = strdup(va_arg(ap, char *)))) {
 
234
                    ERROR_RETURN();
 
235
                }
 
236
                if (!(file = freopen(filename, "w", file))) {
 
237
                    ERROR_RETURN();
 
238
                }
 
239
                break;
 
240
 
 
241
            case EVKEY_BEGIN:
 
242
                valid = 1;
 
243
                RECORD(sprintf(bufpt, ":BEGIN:%s", va_arg(ap, char *)));
 
244
                RECORD(sprintf(bufpt, ":TIME:%.2f", walltime()));
 
245
                break;
 
246
 
 
247
            case EVKEY_END:
 
248
                valid = 1;
 
249
                RECORD(sprintf(bufpt, ":END:%s", va_arg(ap, char *)));
 
250
                RECORD(sprintf(bufpt, ":TIME:%.2f", walltime()));
 
251
                break;
 
252
 
 
253
            case EVKEY_EVENT:
 
254
                valid = 1;
 
255
                RECORD(sprintf(bufpt, ":EVENT:%s", va_arg(ap, char *)));
 
256
                RECORD(sprintf(bufpt, ":TIME:%.2f", walltime()));
 
257
                break;
 
258
 
 
259
            case EVKEY_MSG_LEN:
 
260
                if (!valid) {
 
261
                    ERROR_RETURN();
 
262
                }
 
263
                RECORD(sprintf(bufpt, ":MSG_LEN:%d", va_arg(ap, int)));
 
264
                break;
 
265
 
 
266
            case EVKEY_MSG_TO:
 
267
                if (!valid) {
 
268
                    ERROR_RETURN();
 
269
                }
 
270
                RECORD(sprintf(bufpt, ":MSG_TO:%d", va_arg(ap, int)));
 
271
                break;
 
272
 
 
273
            case EVKEY_MSG_FROM:
 
274
                if (!valid) {
 
275
                    ERROR_RETURN();
 
276
                }
 
277
                RECORD(sprintf(bufpt, ":MSG_FROM:%d", va_arg(ap, int)));
 
278
                break;
 
279
 
 
280
            case EVKEY_MSG_TYPE:
 
281
                if (!valid) {
 
282
                    ERROR_RETURN();
 
283
                }
 
284
                RECORD(sprintf(bufpt, ":MSG_TYPE:%d", va_arg(ap, int)));
 
285
                break;
 
286
 
 
287
            case EVKEY_MSG_SYNC:
 
288
                if (!valid) {
 
289
                    ERROR_RETURN();
 
290
                }
 
291
                RECORD(sprintf(bufpt, ":MSG_SYNC:%d", va_arg(ap, int)));
 
292
                break;
 
293
 
 
294
            case EVKEY_STR_INT:
 
295
                if (!valid) {
 
296
                    ERROR_RETURN();
 
297
                }
 
298
                string  = va_arg(ap, char *);
 
299
                integer = va_arg(ap, int);
 
300
                RECORD(sprintf(bufpt, ":STR_INT:%s:%d", string, integer));
 
301
                break;
 
302
 
 
303
            case EVKEY_STR_DBL:
 
304
                if (!valid) {
 
305
                    ERROR_RETURN();
 
306
                }
 
307
                string  = va_arg(ap, char *);
 
308
                dbl = va_arg(ap, double);
 
309
                RECORD(sprintf(bufpt, ":STR_DBL:%s:%g", string, dbl));
 
310
                break;
 
311
 
 
312
            case EVKEY_STR:
 
313
                if (!valid) {
 
314
                    ERROR_RETURN();
 
315
                }
 
316
                RECORD(sprintf(bufpt, ":STR:%s", va_arg(ap, char *)));
 
317
                break;
 
318
 
 
319
            case EVKEY_DUMP:
 
320
                DUMPBUF();
 
321
                if (temp != bufpt) {
 
322
                    RECORD(sprintf(bufpt, "\n"));
 
323
                    temp = bufpt;
 
324
                }
 
325
                break;
 
326
 
 
327
            default:
 
328
                DUMPBUF();
 
329
                ERROR_RETURN();
 
330
        }
 
331
        key = va_arg(ap, int);
 
332
    }
 
333
 
 
334
done:
 
335
    va_end(ap);
 
336
 
 
337
    /* Put a linefeed on the end of the record if something is written */
 
338
 
 
339
    if (temp != bufpt) {
 
340
        RECORD(sprintf(bufpt, "\n"));
 
341
        temp = bufpt;
 
342
    }
 
343
 
 
344
    /* Should really check on every access to the buffer that there is
 
345
       enough space ... however just assume a very large maximum size
 
346
       for a single event log entry and check here */
 
347
 
 
348
    if (left <= 0) {
 
349
        ERROR_RETURN();
 
350
    }
 
351
 
 
352
    if (left < MAX_EV_LEN) {
 
353
        DUMPBUF();
 
354
    }
 
355
}
 
356
 
 
357
 
 
358
/**
 
359
 * return the wall time in seconds as a double
 
360
 */
 
361
static double walltime()
 
362
{
 
363
    return ((double) MTIME_()) * 0.01;
 
364
}
 
365
 
 
366
 
 
367
/*
 
368
int main(int argc, char **argv)
 
369
{
 
370
    int N = 19;
 
371
    double matrix_norm = 99.1;
 
372
    int niters = 5;
 
373
 
 
374
    evlog(EVKEY_ENABLE, EVKEY_FILENAME, "events.log", EVKEY_LAST_ARG);
 
375
 
 
376
    evlog(EVKEY_EVENT, "Finished startup code",
 
377
            EVKEY_STR, "Now do some real work",
 
378
            EVKEY_LAST_ARG);
 
379
 
 
380
    evlog(EVKEY_BEGIN, "Get Matrix", EVKEY_LAST_ARG);
 
381
 
 
382
    evlog(EVKEY_END, "Get matrix",
 
383
            EVKEY_STR_INT, "Size of matrix", (int) N,
 
384
            EVKEY_STR_DBL, "Norm of matrix", (double) matrix_norm,
 
385
            EVKEY_LAST_ARG);
 
386
 
 
387
    evlog(EVKEY_BEGIN, "Transform matrix",
 
388
            EVKEY_STR_DBL, "Recomputed norm", (double) matrix_norm,
 
389
            EVKEY_LAST_ARG);
 
390
 
 
391
    evlog(EVKEY_END, "Transform matrix",
 
392
            EVKEY_STR_INT, "No. of iterations", (int) niters,
 
393
            EVKEY_LAST_ARG);
 
394
 
 
395
    evlog(EVKEY_DUMP, EVKEY_LAST_ARG);
 
396
 
 
397
    evlog(EVKEY_EVENT, "Logging is disabled ... this should not print",
 
398
            EVKEY_DUMP, EVKEY_LAST_ARG);
 
399
 
 
400
    return 0;
 
401
}
 
402
*/