1#!/usr/bin/python 2 3# Copyright (c) 2014 Kyle Lutz <kyle.r.lutz@gmail.com> 4# Distributed under the Boost Software License, Version 1.0 5# See accompanying file LICENSE_1_0.txt or copy at 6# http://www.boost.org/LICENSE_1_0.txt 7# 8# See http://boostorg.github.com/compute for more information. 9 10# driver script for boost.compute benchmarking. will run a 11# benchmark for a given function (e.g. accumulate, sort). 12 13import os 14import sys 15import subprocess 16 17try: 18 import pylab 19except: 20 print('pylab not found, no ploting...') 21 pass 22 23def run_perf_process(name, size, backend = ""): 24 if not backend: 25 proc = "perf_%s" % name 26 else: 27 proc = "perf_%s_%s" % (backend, name) 28 29 filename = "./perf/" + proc 30 31 if not os.path.isfile(filename): 32 print("Error: failed to find ", filename, " for running") 33 return 0 34 try: 35 output = subprocess.check_output([filename, str(int(size))]) 36 except: 37 return 0 38 39 t = 0 40 for line in output.decode('utf8').split("\n"): 41 if line.startswith("time:"): 42 t = float(line.split(":")[1].split()[0]) 43 44 return t 45 46class Report: 47 def __init__(self, name): 48 self.name = name 49 self.samples = {} 50 51 def add_sample(self, name, size, time): 52 if not name in self.samples: 53 self.samples[name] = [] 54 55 self.samples[name].append((size, time)) 56 57 def display(self): 58 for name in self.samples.keys(): 59 print('=== %s with %s ===' % (self.name, name)) 60 print('size,time (ms)') 61 62 for sample in self.samples[name]: 63 print('%d,%f' % sample) 64 65 def plot_time(self, name): 66 if not name in self.samples: 67 return 68 69 x = [] 70 y = [] 71 72 any_valid_samples = False 73 74 for sample in self.samples[name]: 75 if sample[1] == 0: 76 continue 77 78 x.append(sample[0]) 79 y.append(sample[1]) 80 any_valid_samples = True 81 82 if not any_valid_samples: 83 return 84 85 pylab.loglog(x, y, marker='o', label=name) 86 pylab.xlabel("Size") 87 pylab.ylabel("Time (ms)") 88 pylab.title(self.name) 89 90 def plot_rate(self, name): 91 if not name in self.samples: 92 return 93 94 x = [] 95 y = [] 96 97 any_valid_samples = False 98 99 for sample in self.samples[name]: 100 if sample[1] == 0: 101 continue 102 103 x.append(sample[0]) 104 y.append(float(sample[0]) / (float(sample[1]) * 1e-3)) 105 any_valid_samples = True 106 107 if not any_valid_samples: 108 return 109 110 pylab.loglog(x, y, marker='o', label=name) 111 pylab.xlabel("Size") 112 pylab.ylabel("Rate (values/s)") 113 pylab.title(self.name) 114 115def run_benchmark(name, sizes, vs=[]): 116 report = Report(name) 117 118 for size in sizes: 119 time = run_perf_process(name, size) 120 121 report.add_sample("compute", size, time) 122 123 competitors = { 124 "thrust" : [ 125 "accumulate", 126 "count", 127 "exclusive_scan", 128 "find", 129 "inner_product", 130 "merge", 131 "partial_sum", 132 "partition", 133 "reduce_by_key", 134 "reverse", 135 "reverse_copy", 136 "rotate", 137 "saxpy", 138 "sort", 139 "unique" 140 ], 141 "bolt" : [ 142 "accumulate", 143 "count", 144 "exclusive_scan", 145 "fill", 146 "inner_product", 147 "max_element", 148 "merge", 149 "partial_sum", 150 "reduce_by_key", 151 "saxpy", 152 "sort" 153 ], 154 "tbb": [ 155 "accumulate", 156 "merge", 157 "sort" 158 ], 159 "stl": [ 160 "accumulate", 161 "count", 162 "find", 163 "find_end", 164 "includes", 165 "inner_product", 166 "is_permutation", 167 "max_element", 168 "merge", 169 "next_permutation", 170 "nth_element", 171 "partial_sum", 172 "partition", 173 "partition_point", 174 "prev_permutation", 175 "reverse", 176 "reverse_copy", 177 "rotate", 178 "rotate_copy", 179 "saxpy", 180 "search", 181 "search_n", 182 "set_difference", 183 "set_intersection", 184 "set_symmetric_difference", 185 "set_union", 186 "sort", 187 "stable_partition", 188 "unique", 189 "unique_copy" 190 ] 191 } 192 193 for other in vs: 194 if not other in competitors: 195 continue 196 if not name in competitors[other]: 197 continue 198 199 for size in sizes: 200 time = run_perf_process(name, size, other) 201 report.add_sample(other, size, time) 202 203 return report 204 205if __name__ == '__main__': 206 test = "sort" 207 if len(sys.argv) >= 2: 208 test = sys.argv[1] 209 print('running %s perf test' % test) 210 211 sizes = [ pow(2, x) for x in range(1, 26) ] 212 213 sizes = sorted(sizes) 214 215 competitors = ["bolt", "tbb", "thrust", "stl"] 216 217 report = run_benchmark(test, sizes, competitors) 218 219 plot = None 220 if "--plot-time" in sys.argv: 221 plot = "time" 222 elif "--plot-rate" in sys.argv: 223 plot = "rate" 224 225 if plot == "time": 226 report.plot_time("compute") 227 for competitor in competitors: 228 report.plot_time(competitor) 229 elif plot == "rate": 230 report.plot_rate("compute") 231 for competitor in competitors: 232 report.plot_rate(competitor) 233 234 if plot: 235 pylab.legend(loc='upper left') 236 pylab.show() 237 else: 238 report.display() 239