diff --git a/tests/test_rr_graph_huge.py b/tests/test_rr_graph_huge.py new file mode 100644 index 0000000..72b1aed --- /dev/null +++ b/tests/test_rr_graph_huge.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import sys + +sys.path.insert(0, ".") + +assert sys.argv[1] +exec("from vprgen.rr_graph import %s as rr_graph" % (sys.argv[1],)) + +d = rr_graph.ArchitectureDelegate() + +for i in range(0, int(10000000)): + d.add_edge(i, i+1, 0, {}) + + diff --git a/vprgen/rr_graph/abc.py b/vprgen/rr_graph/abc.py new file mode 100644 index 0000000..88de31e --- /dev/null +++ b/vprgen/rr_graph/abc.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +import abc +from typing import Any, Dict, Iterable, Union + + +class Edge(abc.ABC): + @property + @abc.abstractmethod + def src_node(self) -> int: + raise NotImplemented + + @property + @abc.abstractmethod + def sink_node(self) -> int: + raise NotImplemented + + @property + @abc.abstractmethod + def switch_id(self) -> int: + raise NotImplemented + + @property + @abc.abstractmethod + def metadata(self) -> Union[Dict[str, Any], None]: + """Metadata for edge.""" + raise NotImplemented + + +class Node(abc.ABC): + pass + + +class ArchitectureDelegate(abc.ABC): + @abc.abstractmethod + def edges(self) -> Iterable[Edge]: + raise NotImplemented + diff --git a/vprgen/rr_graph/basic.py b/vprgen/rr_graph/basic.py new file mode 100644 index 0000000..e3d58ea --- /dev/null +++ b/vprgen/rr_graph/basic.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 + +from collections import namedtuple + +from .abc import Edge as EdgeABC +from .abc import ArchitectureDelegate as ArchitectureDelegateABC + +# Implementation using namedtuple +Edge = namedtuple('Edge', ['src_node', 'sink_node', 'switch_id', 'metadata']) +EdgeABC.register(Edge) + + +class ArchitectureDelegate: + def __init__(self): + self.edges = [] + + def add_edge(self, src_node, sink_node, switch_id, metadata={}): + self.edges.append(Edge(src_node, sink_node, switch_id, metadata)) + + def edges(self): + return self.edges + + +ArchitectureDelegateABC.register(ArchitectureDelegate) diff --git a/vprgen/rr_graph/ctypes.py b/vprgen/rr_graph/ctypes.py new file mode 100644 index 0000000..283d56e --- /dev/null +++ b/vprgen/rr_graph/ctypes.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +from ctypes import * + +from .abc import Edge as EdgeABC +from .abc import ArchitectureDelegate as ArchitectureDelegateABC + + +"""Implementation using ctypes.""" + +class Edge(Structure): + _fields_ = [ + ("src_node", c_ulonglong), + ("sink_node", c_ulonglong), + ("switch_id", c_int), + ("metadata", py_object), + ] + + +def array_resize(a, new_size): + assert new_size > a._length_, (new_size, a._length_) + resize(a, sizeof(a._type_)*new_size) + return (a._type_*new_size).from_address(addressof(a)) + + +class ArchitectureDelegate: + def __init__(self): + self.i = 0 + self.s = sizeof(Edge) + + self.edges_l = 10 + self.edges_mem_owner = (Edge * 10)() + self.edges = self.edges_mem_owner + + def add_edge(self, src_node, sink_node, switch_id, metadata={}): + if self.i == self.edges_l: + print("Doubling edges size", self.edges_l, "->", self.edges_l*2) + self.edges_l *= 2 + self.edges = array_resize(self.edges_mem_owner, self.edges_l) + e = self.edges[self.i] + e.src_node = src_node + e.sink_node = sink_node + e.switch_id = switch_id + e.metadata = metadata + self.i += 1 + + def edges(self): + return self.edges[:self.i] + + +ArchitectureDelegateABC.register(ArchitectureDelegate) diff --git a/vprgen/rr_graph/numpy.py b/vprgen/rr_graph/numpy.py new file mode 100644 index 0000000..fe20197 --- /dev/null +++ b/vprgen/rr_graph/numpy.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +import numpy as np + +from .abc import Edge as EdgeABC +from .abc import ArchitectureDelegate as ArchitectureDelegateABC + +"""Implementation using numpy.""" + +Edge = np.dtype([ + ('src_node', '=i8'), # 64bit int + ('sink_node', '=i8'), # 64bit int + ('switch_id', '=i2'), # 16bit int + ('metadata', 'O'), # dict {} +]) + +#EdgeABC.register(Edge) + + +class ArchitectureDelegate: + def __init__(self, hint=10485760): + self.i = 0 + self.edges_mem_owner = np.zeros(hint, dtype=Edge) + self.edges = self.edges_mem_owner.view(np.recarray) + + def add_edge(self, src_node, sink_node, switch_id, metadata={}): + l = len(self.edges) + if self.i == l: + print("Doubling edges size", l, "->", l*2) + del self.edges + self.edges_mem_owner.resize(l*2) + self.edges = self.edges_mem_owner.view(np.recarray) + + e = self.edges[self.i] + e.src_node = src_node + e.sink_node = sink_node + e.switch_id = switch_id + e.metadata = metadata + self.i += 1 + + def edges(self): + return self.edges[:self.i] + + +ArchitectureDelegateABC.register(ArchitectureDelegate)