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

Add device analysis, Makefile and requirements

parent 9cb04b81
No related branches found
No related tags found
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):
def __init__(self, sim, name=None, block=None, resizes_to_check={}, check_properties_resize=False, run_on_device=False):
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._arrays = {}
self._properties = {}
......
......@@ -62,3 +62,25 @@ class AddDeviceCopies(Mutator):
ast_node.stmts = new_stmts
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% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment