now draws something
This commit is contained in:
parent
d49eed6d20
commit
3ffebcbe69
@ -4,8 +4,6 @@ import re
|
|||||||
import math
|
import math
|
||||||
import cairo
|
import cairo
|
||||||
|
|
||||||
WIDTH, HEIGHT = 256, 256
|
|
||||||
|
|
||||||
class ReadFile:
|
class ReadFile:
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
@ -40,20 +38,34 @@ def read_times(rf):
|
|||||||
|
|
||||||
return times[::-1]
|
return times[::-1]
|
||||||
|
|
||||||
class Event:
|
class Thread:
|
||||||
def __init__(self, thread_name, gate_name, start, stop):
|
thread_number = 0
|
||||||
|
|
||||||
|
def __init__(self, thread_name):
|
||||||
self.thread_name = thread_name
|
self.thread_name = thread_name
|
||||||
|
self.thread_number = Thread.thread_number
|
||||||
|
self.events = []
|
||||||
|
Thread.thread_number += 1
|
||||||
|
|
||||||
|
class Event:
|
||||||
|
def __init__(self, thread, gate_name, start, stop):
|
||||||
|
self.thread = thread
|
||||||
self.gate_name = gate_name
|
self.gate_name = gate_name
|
||||||
self.start = start
|
self.start = start
|
||||||
self.stop = stop
|
self.stop = stop
|
||||||
|
|
||||||
if re.match(': work', gate_name):
|
self.work = False
|
||||||
|
self.wait = False
|
||||||
|
if re.match('.*: .*work.*', gate_name):
|
||||||
self.work = True
|
self.work = True
|
||||||
if re.match(': wait', gate_name):
|
if re.match('.*: .*wait.*', gate_name):
|
||||||
self.wait = True
|
self.wait = True
|
||||||
|
|
||||||
events = []
|
thread.events.append(self)
|
||||||
|
|
||||||
thread_id = 0
|
thread_id = 0
|
||||||
|
threads = []
|
||||||
|
n_events = 0
|
||||||
with ReadFile('vips-profile.txt') as rf:
|
with ReadFile('vips-profile.txt') as rf:
|
||||||
while rf:
|
while rf:
|
||||||
match = re.match('thread: (.*)', rf.line)
|
match = re.match('thread: (.*)', rf.line)
|
||||||
@ -61,6 +73,8 @@ with ReadFile('vips-profile.txt') as rf:
|
|||||||
print 'parse error line %d, expected "thread"' % rf.lineno
|
print 'parse error line %d, expected "thread"' % rf.lineno
|
||||||
thread_name = match.group(1) + " " + str(thread_id)
|
thread_name = match.group(1) + " " + str(thread_id)
|
||||||
thread_id += 1
|
thread_id += 1
|
||||||
|
thread = Thread(thread_name)
|
||||||
|
threads.append(thread)
|
||||||
rf.getnext()
|
rf.getnext()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@ -88,54 +102,95 @@ with ReadFile('vips-profile.txt') as rf:
|
|||||||
print 'start and stop length mismatch'
|
print 'start and stop length mismatch'
|
||||||
|
|
||||||
for a, b in zip(start, stop):
|
for a, b in zip(start, stop):
|
||||||
event = Event(thread_name, gate_name, a, b)
|
Event(thread, gate_name, a, b)
|
||||||
events.append(event)
|
n_events += 1
|
||||||
|
|
||||||
events.sort(lambda x, y: cmp(x.start, y.start))
|
for thread in threads:
|
||||||
|
thread.events.sort(lambda x, y: cmp(x.start, y.start))
|
||||||
|
|
||||||
print 'loaded %d events' % len(events)
|
print 'loaded %d events' % n_events
|
||||||
|
|
||||||
# normalise time axis to secs of computation
|
# normalise time axis to secs of computation
|
||||||
ticks_per_sec = 1000000.0
|
ticks_per_sec = 1000000.0
|
||||||
start_time = events[0].start
|
start_time = threads[0].events[0].start
|
||||||
for event in events:
|
last_time = 0
|
||||||
event.start = (event.start - start_time) / ticks_per_sec
|
for thread in threads:
|
||||||
event.stop = (event.stop - start_time) / ticks_per_sec
|
for event in thread.events:
|
||||||
last_time = events[-1].stop
|
event.start = (event.start - start_time) / ticks_per_sec
|
||||||
|
event.stop = (event.stop - start_time) / ticks_per_sec
|
||||||
|
|
||||||
|
if event.stop > last_time:
|
||||||
|
last_time = event.stop
|
||||||
|
|
||||||
print 'last time =', last_time
|
print 'last time =', last_time
|
||||||
|
|
||||||
# within each thread, allocate a Y position
|
# do two gates overlap?
|
||||||
threads = []
|
def is_overlap(events, gate_name1, gate_name2):
|
||||||
for event in events:
|
for event1 in events:
|
||||||
if not event.thread_name in threads:
|
if event1.gate_name != gate_name1:
|
||||||
threads.append(event.thread_name)
|
continue
|
||||||
|
|
||||||
|
for event2 in events:
|
||||||
|
if event2.gate_name != gate_name2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# if either endpoint of 1 is within 2
|
||||||
|
if event1.start > event2.start and event1.stop < event2.stop:
|
||||||
|
return True
|
||||||
|
if event1.stop > event2.start and event1.stop < event2.stop:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
# allocate a y position for each gate
|
||||||
|
total_y = 0
|
||||||
|
for thread in threads:
|
||||||
|
y = 1
|
||||||
|
gate_positions = {}
|
||||||
|
for event in thread.events:
|
||||||
|
if event.work or event.wait:
|
||||||
|
gate_positions[event.gate_name] = 0
|
||||||
|
elif not event.gate_name in gate_positions:
|
||||||
|
overlap = True
|
||||||
|
for gate_name in gate_positions:
|
||||||
|
if not is_overlap(thread.events, gate_name, event.gate_name):
|
||||||
|
gate_positions[event.gate_name] = gate_positions[gate_name]
|
||||||
|
overlap = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if overlap:
|
||||||
|
gate_positions[event.gate_name] = y
|
||||||
|
y += 1
|
||||||
|
|
||||||
|
event.y = gate_positions[event.gate_name]
|
||||||
|
event.total_y = total_y + y
|
||||||
|
|
||||||
|
total_y += y
|
||||||
|
|
||||||
|
PIXELS_PER_SECOND = 1000
|
||||||
|
PIXELS_PER_GATE = 20
|
||||||
|
WIDTH = int(last_time * PIXELS_PER_SECOND)
|
||||||
|
HEIGHT = int(total_y * PIXELS_PER_GATE)
|
||||||
|
|
||||||
surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
|
surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
|
||||||
ctx = cairo.Context (surface)
|
ctx = cairo.Context (surface)
|
||||||
|
|
||||||
ctx.scale (WIDTH, HEIGHT) # Normalizing the canvas
|
ctx.scale (PIXELS_PER_SECOND, PIXELS_PER_GATE)
|
||||||
|
|
||||||
pat = cairo.LinearGradient (0.0, 0.0, 0.0, 1.0)
|
for thread in threads:
|
||||||
pat.add_color_stop_rgba (1, 0.7, 0, 0, 0.5) # First stop, 50% opacity
|
for event in thread.events:
|
||||||
pat.add_color_stop_rgba (0, 0.9, 0.7, 0.2, 1) # Last stop, 100% opacity
|
ctx.move_to (event.start, event.total_y)
|
||||||
|
ctx.line_to (event.stop, event.total_y)
|
||||||
|
ctx.close_path ()
|
||||||
|
ctx.set_line_width (0.5)
|
||||||
|
|
||||||
ctx.rectangle (0, 0, 1, 1) # Rectangle(x0, y0, x1, y1)
|
if event.wait:
|
||||||
ctx.set_source (pat)
|
ctx.set_source_rgb (0.9, 0.1, 0.1)
|
||||||
ctx.fill ()
|
elif event.work:
|
||||||
|
ctx.set_source_rgb (0.1, 0.9, 0.1)
|
||||||
|
else:
|
||||||
|
ctx.set_source_rgb (0.1, 0.1, 0.9)
|
||||||
|
|
||||||
ctx.translate (0.1, 0.1) # Changing the current transformation matrix
|
ctx.stroke ()
|
||||||
|
|
||||||
ctx.move_to (0, 0)
|
|
||||||
ctx.arc (0.2, 0.1, 0.1, -math.pi/2, 0) # Arc(cx, cy, radius, start_angle, stop_angle)
|
|
||||||
ctx.line_to (0.5, 0.1) # Line to (x,y)
|
|
||||||
ctx.curve_to (0.5, 0.2, 0.5, 0.4, 0.2, 0.8) # Curve(x1, y1, x2, y2, x3, y3)
|
|
||||||
ctx.close_path ()
|
|
||||||
|
|
||||||
ctx.set_source_rgb (0.3, 0.2, 0.5) # Solid color
|
|
||||||
ctx.set_line_width (0.02)
|
|
||||||
ctx.stroke ()
|
|
||||||
|
|
||||||
surface.write_to_png ("example.png") # Output to PNG
|
surface.write_to_png ("example.png") # Output to PNG
|
||||||
|
Loading…
Reference in New Issue
Block a user