apmpi-backend.py 3.13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
import cffi
import ctypes

import numpy as np
import darshan.backend.cffi_backend

# APMPI structure defs
structdefs = '''
struct darshan_apmpi_perf_record
{
    struct darshan_base_record base_rec;
12 13
    uint64_t counters[396];
    double fcounters[222];
14 15
    double fsynccounters[16];
    double fglobalcounters[2];
16
    char   node_name[128];
17 18 19
};
struct darshan_apmpi_header_record
{
20
    struct darshan_base_record base_rec;  
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
    int64_t magic;
    double apmpi_f_variance_total_mpitime;
    double apmpi_f_variance_total_mpisynctime;
};

extern char *apmpi_counter_names[];
extern char *apmpi_f_mpiop_totaltime_counter_names[]; 
extern char *apmpi_f_mpiop_synctime_counter_names[];
extern char *apmpi_f_mpi_global_counter_names[];

'''

def get_apmpi_defs():
  return structdefs


# load header record
def log_get_apmpi_record(log, dtype='dict'):
    from darshan.backend.cffi_backend import ffi, libdutil, log_get_modules, counter_names

    mod_name = 'APMPI'
    modules = log_get_modules(log)


    rec = {}
    buf = ffi.new("void **")
    r = libdutil.darshan_log_get_record(log['handle'], modules[mod_name]['idx'], buf)
    if r < 1:
        return None

    hdr = ffi.cast('struct darshan_apmpi_header_record **', buf)
    prf = ffi.cast('struct darshan_apmpi_perf_record **', buf)

    rec['id'] = hdr[0].base_rec.id
    rec['rank'] = hdr[0].base_rec.rank

    if hdr[0].magic == 280520118345:
      rec['magic'] = hdr[0].magic
      rec['variance_total_mpitime'] = hdr[0].apmpi_f_variance_total_mpitime
      rec['variance_total_mpisynctime'] = hdr[0].apmpi_f_variance_total_mpisynctime
    else:
62
      buf = ffi.new("char[]", 128)
63
      rec['node_name'] = ffi.string(prf[0].node_name).decode("utf-8")
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

      lst = []
      for i in range(0, len(prf[0].counters)):
        lst.append(prf[0].counters[i])
        np_counters = np.array(lst, dtype=np.uint64)
        d_counters = dict(zip(counter_names(mod_name), np_counters))

      lst = []
      for i in range(0, len(prf[0].fcounters)):
        lst.append(prf[0].fcounters[i])
        np_fcounters = np.array(lst, dtype=np.float64)
        d_fcounters = dict(zip(counter_names(mod_name, fcnts=True, special='mpiop_totaltime_'), np_fcounters))

      lst = []
      for i in range(0, len(prf[0].fsynccounters)):
        lst.append(prf[0].fsynccounters[i])
        np_fsynccounters = np.array(lst, dtype=np.float64)
        d_fsynccounters = dict(zip(counter_names(mod_name, fcnts=True, special='mpiop_synctime_'), np_fsynccounters))

      lst = []
      for i in range(0, len(prf[0].fglobalcounters)):
        lst.append(prf[0].fglobalcounters[i])
        np_fglobalcounters = np.array(lst, dtype=np.float64)
        d_fglobalcounters = dict(zip(counter_names(mod_name, fcnts=True, special='mpi_global_'), np_fglobalcounters))

      if dtype == 'numpy':
        rec['counters'] = np_counters
        rec['fcounters'] = np_fcounters
        rec['fsynccounters'] = np_fsynccounters
        rec['fglobalcounters'] = np_fglobalcounters
      else:
        rec['counters'] = d_counters
        rec['fcounters'] = d_fcounters
        rec['fsynccounters'] = d_fsynccounters
        rec['fglobalcounters'] = d_fglobalcounters
    
    return rec