xref: /petsc/src/benchmarks/streams/process.py (revision feff33ee0b5b037fa8f9f294dede656a2f85cc47)
1#!/usr/bin/env python
2#!/bin/env python
3#
4#    Computers speed up of Streams benchmark results generated by make streams and plots
5#
6#    matplotlib can switch between different backends hence this needs to be run
7#    twice to first generate a file and then display a window
8#
9from __future__ import print_function
10import os
11#
12def process(fileoutput = 1):
13  import re
14  ff = open('scaling.log')
15  data = ff.read()
16  ff.close()
17
18  s = data.split('\n')
19  ss = []
20  for i in s:
21    if not i.startswith('MPI rank'):
22      ss.append(i)
23  data = '\n'.join(ss)
24  hosts  = {}
25  triads = {}
26  speedups = {}
27  match = data.split('Number of MPI processes ')
28  for i in match:
29    if i:
30      fields = i.split('\n')
31      size = int(fields[0].split()[0])
32      hosts[size] = fields[0].split()[3:]
33      triads[size] = float(fields[1].split()[1])
34
35  if len(hosts) < 2: return
36
37  ff = open('scaling.log','a')
38  if fileoutput: print('np  speedup')
39  if fileoutput: ff.write('np  speedup\n')
40  for sizes in hosts:
41    speedups[sizes] = triads[sizes]/triads[1]
42    if fileoutput: print(sizes,round(triads[sizes]/triads[1],2))
43    if fileoutput: ff.write(str(sizes)+' '+str(round(triads[sizes]/triads[1],2))+'\n')
44
45  if fileoutput: print("Estimation of possible speedup of MPI programs based on Streams benchmark.")
46  if fileoutput: ff.write("Estimation of possible speedup of MPI programs based on Streams benchmark.\n")
47
48  if fileoutput:
49    import re
50    last = max(hosts.keys())
51    lasthosts = hosts[last]
52    for i in range(0,len(lasthosts)):
53      lasthosts[i] = re.sub(r"Process [0-9]*", "", lasthosts[i])
54    ulasthosts = list(set(lasthosts))
55    print("It appears you have "+str(len(ulasthosts))+" node(s)")
56    ff.write("It appears you have "+str(len(ulasthosts))+" node(s)\n")
57
58    if len(ulasthosts) < 1:
59      testhosts = []
60      for i in range(0,len(lasthosts)):
61        testhosts.append(ulasthosts[i % len(ulasthosts)])
62      if testhosts == lasthosts:
63        print("   distributed in a round robin order")
64        ff.write("   distributed in a round robin order\n")
65      else:
66        print("   NOT distributed in a round robin order")
67        ff.write("   NOT distributed in a round robin order\n")
68
69  try:
70    import matplotlib
71  except:
72    print("Unable to open matplotlib to plot speedup")
73    return
74
75  try:
76    if fileoutput: matplotlib.use('Agg')
77    import matplotlib.pyplot as plt
78  except:
79    print("Unable to open matplotlib to plot speedup")
80    return
81
82  try:
83    fig, ax1 = plt.subplots()
84    plt.title('MPI Perfect and Streams Speedup')
85    ax2 = ax1.twinx()
86    ax1.set_autoscaley_on(False)
87
88    # make sure that actual bandwidth values (as opposed to perfect speedup) takes
89    # at least a third of the y axis
90    ymax = min(max(hosts.keys()), 3*max(triads.values())/min(triads.values()) - 2)
91
92    ax1.set_xlim([min(hosts.keys()),max(hosts.keys())])
93    ax1.set_ylim([min(hosts.keys()),ymax])
94    ax1.set_xlabel('Number of MPI processes')
95    ax1.set_ylabel('Memory Bandwidth Speedup')
96    ax1.plot(hosts.keys(),hosts.keys(),'b',hosts.keys(),speedups.values(),'r-o')
97    ax2.set_autoscaley_on(False)
98    ax2.set_xlim([min(hosts.keys()),max(hosts.keys())])
99    ax2.set_ylim([min(triads.values())/1000.,min(triads.values())*ymax/1000.])
100    ax2.set_ylabel("Achieved Bandwidth. Gigabytes per Second")
101
102    plt.show()
103    if fileoutput: plt.savefig('scaling.png')
104    if fileoutput: print("See graph in the file src/benchmarks/streams/scaling.png")
105    if fileoutput: ff.write("See graph in the file src/benchmarks/streams/scaling.png\n")
106  except Exception as e:
107    if fileoutput: print("Unable to plot speedup to a file")
108    else: print("Unable to display speedup plot")
109    return
110
111  ff.close()
112
113#
114#
115if __name__ ==  '__main__':
116  import sys
117  process(len(sys.argv)-1)
118
119
120