Skip to content
Snippets Groups Projects
Commit 34437e34 authored by Rafael Ravedutti's avatar Rafael Ravedutti
Browse files

Add device analysis, Makefile and requirements


Signed-off-by: default avatarRafael Ravedutti <rafaelravedutti@gmail.com>
parent 9cb04b81
No related merge requests found
Makefile 0 → 100644
.PHONY: all build clean lj_ns
all: build lj_ns clean
@echo "Everything was done!"
build:
@echo "Building pairs package..."
python3 setup.py build && python3 setup.py install --user
lj_ns:
@echo "Generating and compiling CPP for Lennard-Jones example..."
python3 examples/lj_func.py
g++ -o lj_ns lj_ns.cpp
clean:
@echo "Cleaning..."
rm -rf build lj_ns lj_ns.cpp dist pairs.egg-info kernels kernels.pdf
from pairs.ir.visitor import Visitor
class FetchKernelReferences(Visitor):
def __init__(self, ast):
super().__init__(ast)
self.kernel_stack = []
self.kernel_decls = {}
self.kernel_used_bin_ops = {}
self.writing = False
def visit_ArrayAccess(self, ast_node):
# Visit array and save current writing state
self.visit(ast_node.array)
writing_state = self.writing
# Index elements are read-only
self.writing = False
self.visit([roc for roc in ast_node.children() if roc != ast_node.array])
self.writing = writing_state
def visit_Assign(self, ast_node):
self.writing = True
self.visit(ast_node.destinations())
self.writing = False
self.visit(ast_node.sources())
def visit_Kernel(self, ast_node):
kernel_id = ast_node.kernel_id
self.kernel_decls[kernel_id] = []
self.kernel_used_bin_ops[kernel_id] = []
self.kernel_stack.append(ast_node)
self.visit_children(ast_node)
self.kernel_stack.pop()
ast_node.add_bin_op([b for b in self.kernel_used_bin_ops[kernel_id] if b not in self.kernel_decls[kernel_id]])
def visit_PropertyAccess(self, ast_node):
# Visit property and save current writing state
self.visit(ast_node.prop)
writing_state = self.writing
# Index elements are read-only
self.writing = False
self.visit([roc for roc in ast_node.children() if roc != ast_node.prop])
self.writing = writing_state
def visit_Decl(self, ast_node):
if isinstance(ast_node.elem, BinOp):
for k in self.kernel_stack:
self.kernel_decls[k.kernel_id].append(ast_node)
def visit_BinOp(self, ast_node):
for k in self.kernel_stack:
self.kernel_used_bin_ops[k.kernel_id].append(ast_node)
def visit_Array(self, ast_node):
for k in self.kernel_stack:
k.add_array(ast_node, self.writing)
def visit_Property(self, ast_node):
for k in self.kernel_stack:
k.add_property(ast_node, self.writing)
def visit_Var(self, ast_node):
for k in self.kernel_stack:
k.add_variable(ast_node, self.writing)
from pairs.ir.arrays import Array
from pairs.ir.ast_node import ASTNode
from pairs.ir.properties import Property
from pairs.ir.variables import Var
class Kernel(ASTNode):
last_kernel = 0
def __init__(self, sim, name=None, block=None):
super().__init__(sim)
self._id = Kernel.last_kernel
self._name = name if name is not None else "kernel" + str(Kernel.last_kernel)
self._variables = {}
self._arrays = {}
self._properties = {}
self._bin_ops = []
self._block = block
sim.add_kernel(self)
Kernel.last_kernel += 1
@property
def kernel_id(self):
return self._id
@property
def name(self):
return self._name
@property
def block(self):
return self._block
def variables(self):
return self._variables
def read_only_variables(self):
return [v for v in self._variables if 'w' not in self._variables[v]]
def write_variables(self):
return [v for v in self._variables if 'w' in self._variables[v]]
def arrays(self):
return self._arrays
def properties(self):
return self._properties
def properties_to_synchronize(self):
return {p for p in self._properties if self._properties[p][0] == 'r'}
def write_properties(self):
return {p for p in self._properties if 'w' in self._properties[p]}
def add_array(self, array, write=False):
array_list = array if isinstance(array, list) else [array]
character = 'w' if write else 'r'
for a in array_list:
assert isinstance(a, Array), "Kernel.add_array(): given element is not of type Array!"
self._arrays[a] = character if a not in self._arrays else self._arrays[a] + character
def add_variable(self, variable, write=False):
variable_list = variable if isinstance(variable, list) else [variable]
character = 'w' if write else 'r'
for v in variable_list:
assert isinstance(v, Var), "Kernel.add_variable(): given element is not of type Var!"
self._variables[v] = character if v not in self._variables else self._variables[v] + character
def add_property(self, prop, write=False):
prop_list = prop if isinstance(prop, list) else [prop]
character = 'w' if write else 'r'
for p in prop_list:
assert isinstance(p, Property), "Kernel.add_property(): given element is not of type Property!"
self._properties[p] = character if p not in self._properties else self._properties[p] + character
def add_bin_op(self, bin_op):
bin_op_list = bin_op if isinstance(bin_op, list) else [bin_op]
for b in bin_op_list:
assert isinstance(b, BinOp), "Kernel.add_bin_op(): given element is not of type BinOp!"
self._bin_ops.append(b)
def children(self):
return [self._block]
class KernelLaunch(ASTNode):
def __init__(self, sim, kernel, iterator, range_min, range_max):
assert isinstance(module, Kernel), "KernelLaunch(): given parameter is not of type Kernel!"
super().__init__(sim)
self._kernel = kernel
self._iterator = iterator
self._range_min = range_min
self._range_max = range_max
@property
def kernel(self):
return self._kernel
...@@ -9,7 +9,7 @@ class Module(ASTNode): ...@@ -9,7 +9,7 @@ class Module(ASTNode):
def __init__(self, sim, name=None, block=None, resizes_to_check={}, check_properties_resize=False, run_on_device=False): def __init__(self, sim, name=None, block=None, resizes_to_check={}, check_properties_resize=False, run_on_device=False):
super().__init__(sim) super().__init__(sim)
self._name = name if name is not None else "module_" + str(Module.last_module) self._name = name if name is not None else "module" + str(Module.last_module)
self._variables = {} self._variables = {}
self._arrays = {} self._arrays = {}
self._properties = {} self._properties = {}
......
...@@ -62,3 +62,25 @@ class AddDeviceCopies(Mutator): ...@@ -62,3 +62,25 @@ class AddDeviceCopies(Mutator):
ast_node.stmts = new_stmts ast_node.stmts = new_stmts
return ast_node return ast_node
class AddDeviceKernels(Mutator):
def __init__(self, ast):
super().__init__(ast)
def mutate_Module(self, ast_node):
ast_node._block = self.mutate(ast_node._block)
if ast_node.run_on_device:
new_stmts = []
kernel_id = 0
for s in ast_node._block.stmts:
if s is not None:
if isinstance(s, For) and (not isinstance(s.min, Lit) or not isinstance(s.max, Lit)):
kernel = Kernel(ast_node.sim, f"{ast_node.name}_kernel{kernel_id}", s.block)
new_stmts.append(KernelLaunch(ast_node.sim, kernel, s.iterator, s.min, s.max))
kernel_id += 1
else:
new_stmts.append(s)
return ast_node
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment