Skip to content

Instantly share code, notes, and snippets.

@vrld
Last active December 24, 2015 12:09
Show Gist options
  • Save vrld/6795625 to your computer and use it in GitHub Desktop.
Save vrld/6795625 to your computer and use it in GitHub Desktop.
Simple Module Pipeline Thingy
class Constant(Module):
def __init__(self, val = 0):
self.out = val
def __repr__(self):
return 'Constant({})'.format(self.out)
class Mul(Module):
def __repr__(self):
return 'Mul()'
def tick(self):
self.out = self.a * self.b
class Printer(Module):
def __init__(self, name):
self.name = name
def __repr__(self):
return 'Printer({})'.format(self.name)
def tick(self):
print self.name + ':', self.inp
def main():
const = Constant(3)
m1 = Mul()
m2 = Mul()
p1 = Printer('P1')
p2 = Printer('P2')
p3 = Printer('P3')
sched = Scheduler()
sched.connect(const, 'out', p1, 'inp')
sched.connect(const, 'out', m1, 'a')
sched.connect(const, 'out', m1, 'b')
sched.connect(m1, 'out', p2, 'inp')
sched.connect(m1, 'out', m2, 'a')
sched.connect(m1, 'out', m2, 'b')
sched.connect(m2, 'out', p3, 'inp')
for i in range(3,6):
const.out = i
sched.tick()
if __name__ == '__main__':
main()
# output:
# P1: 3
# P2: 9
# P3: 81
#
# P1: 4
# P2: 16
# P3: 256
#
# P1: 5
# P2: 25
# P3: 625
from collections import defaultdict
class Module:
def tick(self): pass
def inputs(): return {}
def outputs(): return {}
class Scheduler(Module):
def __init__(self, slots = None):
self.slots = defaultdict(list) if slots is None else slots
self.levels = None
def __repr__(self):
return 'Scheduler(slots = {})'.format(self.slots)
def connect(self, source, slot_source, sink, slot_sink):
self.slots[sink].append((slot_sink, source, slot_source))
self.levels = None
return self
def build_tree(self):
# collect modules
children = defaultdict(set)
for sink in self.slots:
children[sink] # creates set if not existing
for _, source, _ in self.slots[sink]:
children[source].add(sink)
# find module levels
def find_levels(modules, l = 0, levels = defaultdict(int)):
for m in modules:
levels[m] = max(levels[m], l)
find_levels(children[m], l+1, levels)
return levels
levels = find_levels([m for m in children if m not in self.slots])
# finally: record modules in processing order structure
self.levels = [set() for i in range(max(levels.values())+1)]
for m in children:
self.levels[levels[m]].add(m)
return self
def tick(self):
if self.levels is None:
self.build_tree()
for level in self.levels:
for obj in level:
for slot_sink, source, slot_source in self.slots[obj]:
obj.__dict__[slot_sink] = source.__dict__[slot_source]
obj.tick()
return self
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment