| 1 | #!/usr/bin/python3
 | 
|---|
| 2 | 
 | 
|---|
| 3 | import argparse, json, math, sys, time
 | 
|---|
| 4 | import multiprocessing
 | 
|---|
| 5 | from PIL import Image
 | 
|---|
| 6 | import numpy as np
 | 
|---|
| 7 | 
 | 
|---|
| 8 | class Timed:
 | 
|---|
| 9 |         def __init__(self, text):
 | 
|---|
| 10 |                 print(text, end='', flush=True)
 | 
|---|
| 11 | 
 | 
|---|
| 12 |         def pretty(self, durr):
 | 
|---|
| 13 |                 seconds = int(durr)
 | 
|---|
| 14 |                 days, seconds = divmod(seconds, 86400)
 | 
|---|
| 15 |                 hours, seconds = divmod(seconds, 3600)
 | 
|---|
| 16 |                 minutes, seconds = divmod(seconds, 60)
 | 
|---|
| 17 |                 if days > 0:
 | 
|---|
| 18 |                         return '%dd%dh%dm%ds' % (days, hours, minutes, seconds)
 | 
|---|
| 19 |                 elif hours > 0:
 | 
|---|
| 20 |                         return '%dh%dm%ds' % (hours, minutes, seconds)
 | 
|---|
| 21 |                 elif minutes > 0:
 | 
|---|
| 22 |                         return '%dm%ds' % (minutes, seconds)
 | 
|---|
| 23 |                 else:
 | 
|---|
| 24 |                         return '%ds' % (seconds,)
 | 
|---|
| 25 | 
 | 
|---|
| 26 |         def __enter__(self):
 | 
|---|
| 27 |                 self.start = time.time()
 | 
|---|
| 28 |                 return self
 | 
|---|
| 29 | 
 | 
|---|
| 30 |         def __exit__(self, *args):
 | 
|---|
| 31 |                 self.end = time.time()
 | 
|---|
| 32 |                 print(self.pretty(self.end - self.start))
 | 
|---|
| 33 | 
 | 
|---|
| 34 | 
 | 
|---|
| 35 | 
 | 
|---|
| 36 | parser = argparse.ArgumentParser()
 | 
|---|
| 37 | parser.add_argument('--infile', type=argparse.FileType('r'), default=sys.stdin)
 | 
|---|
| 38 | parser.add_argument('--outfile', type=str, default='out.png')
 | 
|---|
| 39 | 
 | 
|---|
| 40 | args = parser.parse_args()
 | 
|---|
| 41 | 
 | 
|---|
| 42 | pool = multiprocessing.Pool()
 | 
|---|
| 43 | 
 | 
|---|
| 44 | with Timed("Loading json..."):
 | 
|---|
| 45 |         obj = json.load(args.infile)
 | 
|---|
| 46 | 
 | 
|---|
| 47 | min_tsc = int(obj['min-tsc'])
 | 
|---|
| 48 | max_tsc = int(obj['max-tsc'])
 | 
|---|
| 49 | 
 | 
|---|
| 50 | def tsc_to_s(tsc):
 | 
|---|
| 51 |         return float(tsc - min_tsc)  / 2500000000.0
 | 
|---|
| 52 | 
 | 
|---|
| 53 | max_sec = tsc_to_s(max_tsc)
 | 
|---|
| 54 | print([min_tsc, max_tsc, max_sec])
 | 
|---|
| 55 | 
 | 
|---|
| 56 | min_cpu = int(obj['min-cpu'])
 | 
|---|
| 57 | max_cpu = int(obj['max-cpu'])
 | 
|---|
| 58 | cnt_cpu = max_cpu - min_cpu + 1
 | 
|---|
| 59 | nbins = math.ceil(max_sec * 10)
 | 
|---|
| 60 | 
 | 
|---|
| 61 | class Bar:
 | 
|---|
| 62 |         def __init__(self):
 | 
|---|
| 63 |                 pass
 | 
|---|
| 64 | 
 | 
|---|
| 65 | with Timed("Creating bins..."):
 | 
|---|
| 66 |         bins = []
 | 
|---|
| 67 |         for _ in range(0, int(nbins)):
 | 
|---|
| 68 |                 bar = Bar()
 | 
|---|
| 69 |                 bins.append([bar, *[*([0] * cnt_cpu), bar] * cnt_cpu])
 | 
|---|
| 70 |                 # bins.append([0] * cnt_cpu)
 | 
|---|
| 71 | 
 | 
|---|
| 72 |         bins = np.array(bins)
 | 
|---|
| 73 | 
 | 
|---|
| 74 | 
 | 
|---|
| 75 | 
 | 
|---|
| 76 | def flatten(val):
 | 
|---|
| 77 |         secs = tsc_to_s(val[1])
 | 
|---|
| 78 |         ratio = secs / max_sec
 | 
|---|
| 79 |         b = int(ratio * (nbins - 1))
 | 
|---|
| 80 |         ## from/to
 | 
|---|
| 81 |         from_ = val[2] - min_cpu
 | 
|---|
| 82 |         to_   = val[3] - min_cpu
 | 
|---|
| 83 |         idx = int(1 + ((cnt_cpu + 1) * to_) + from_)
 | 
|---|
| 84 |         return [b, idx, 1]
 | 
|---|
| 85 |         ## val per cpu
 | 
|---|
| 86 |         # cnt = val[2]
 | 
|---|
| 87 |         # idx = val[3] - min_cpu
 | 
|---|
| 88 |         # # idx = from_
 | 
|---|
| 89 |         # return [b, idx, cnt]
 | 
|---|
| 90 | 
 | 
|---|
| 91 | 
 | 
|---|
| 92 | with Timed("Compressing data..."):
 | 
|---|
| 93 |         compress = map(flatten, obj['values'])
 | 
|---|
| 94 | 
 | 
|---|
| 95 | highest  = 1
 | 
|---|
| 96 | with Timed("Grouping data..."):
 | 
|---|
| 97 |         for x in compress:
 | 
|---|
| 98 |                 bins[x[0]][x[1]] += x[2]
 | 
|---|
| 99 |                 highest = max(highest, bins[x[0]][x[1]])
 | 
|---|
| 100 | 
 | 
|---|
| 101 | print(highest)
 | 
|---|
| 102 | # highest  = 10000000000
 | 
|---|
| 103 | 
 | 
|---|
| 104 | with Timed("Normalizing data..."):
 | 
|---|
| 105 |         def normalize(v):
 | 
|---|
| 106 |                 if type(v) is Bar:
 | 
|---|
| 107 |                         return np.uint32(0xff008000)
 | 
|---|
| 108 |                 v = v * 255 / float(highest)
 | 
|---|
| 109 |                 if v > 256:
 | 
|---|
| 110 |                         v = 255
 | 
|---|
| 111 |                 u8 = np.uint8(v)
 | 
|---|
| 112 |                 u32 = np.uint32(u8)
 | 
|---|
| 113 | 
 | 
|---|
| 114 |                 return (0xff << 24) | (u32 << 16) | (u32 << 8) | (u32 << 0)
 | 
|---|
| 115 |         normalizef = np.vectorize(normalize, [np.uint32])
 | 
|---|
| 116 | 
 | 
|---|
| 117 |         bins = normalizef(bins)
 | 
|---|
| 118 | 
 | 
|---|
| 119 | print(bins.shape)
 | 
|---|
| 120 | with Timed("Saving image..."):
 | 
|---|
| 121 |         im = Image.fromarray(bins, mode='RGBA')
 | 
|---|
| 122 |         im.show()
 | 
|---|
| 123 |         im.save(args.outfile)
 | 
|---|