Belle II Software development
resource_analyzer.py
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import ROOT
5import math
6import json
7import csv
8
9
10result = {'modules': {}, 'sums': {}}
11
12# extract module statistics and memory usage from log file
13log = open('resources.log', errors='ignore')
14in_summary = False
15for line in log:
16 if in_summary and not line.startswith('================================================================================='):
17 module = line.split('|')[0].strip()
18 mem = max(int(line.split('|')[2]), 0)
19 time_str = line.split('|')[4].split('+')
20 time = float(time_str[0])
21 time_error = float(time_str[1][1:])
22 data = {'mem': mem, 'time': time, 'time_error': time_error, 'mem_init': 0, 'mem_begin_run': 0, 'mem_event': 0, 'mem_end_run': 0, 'mem_term': 0, 'mem_total': 0}
23 if module.startswith('Sum_'):
24 result['sums'][module[4:]] = data
25 continue
26 if module == 'Total':
27 events = int(line.split('|')[1]) - 1
28 factor = events / (events + 1.0)
29 result['total'] = {'mem': mem, 'time': time * factor, 'time_error': time_error * factor}
30 break
31 if module in result['modules'].keys():
32 result['modules'][module]['mem'] += data['mem']
33 result['modules'][module]['time'] += data['time']
34 result['modules'][module]['time_error'] = math.sqrt(result['modules'][module]['time_error']**2 + data['time_error']**2)
35 else:
36 result['modules'][module] = data
37 if line.startswith('Name ') and line.endswith(' | Calls | Memory(MB) | Time(s) | Time(ms)/Call\n'):
38 in_summary = True
39 if line.startswith('[INFO] Virtual Memory usage at termination [MB]:'):
40 result['vmem'] = line.split()[-1]
41 if line.startswith('[INFO] Rss Memory usage at termination [MB] :'):
42 result['rss'] = line.split()[-1]
43
44# extract size information from mdst and dst output
45ROOT.gErrorIgnoreLevel = ROOT.kWarning + 1
46for type in ['mdst', 'dst']:
47 result[f'{type}_branches'] = {}
48 file = ROOT.TFile(f'{type}.root')
49 tree = file.Get('tree')
50 root_events = tree.GetEntriesFast() * 1.0
51 for branch in tree.GetListOfBranches():
52 result[f'{type}_branches'][branch.GetName()] = branch.GetZipBytes('*') / root_events / 1024
53 result[f'{type}_size'] = tree.GetZipBytes() / root_events / 1024
54
55# extract memory usage from csv file
56with open('memcheck.csv', 'r', errors='replace') as csvFile:
57 reader = csv.DictReader(csvFile)
58 for row in reader:
59 module = row['name']
60 if module in result['modules'].keys():
61 result['modules'][module]['mem_init'] += float(row['memory init'])
62 result['modules'][module]['mem_begin_run'] += float(row['memory begin_run'])
63 result['modules'][module]['mem_event'] += float(row['memory event'])
64 result['modules'][module]['mem_end_run'] += float(row['memory end_run'])
65 result['modules'][module]['mem_term'] += float(row['memory term'])
66 result['modules'][module]['mem_total'] += float(row['memory total'])
67
68# write result file
69with open('resources.json', 'w') as resources_file:
70 json.dump(result, resources_file)