def create_range_conn(s, chan, i_elem, group): diff2 = group[0] elem0 = group[1][0][0] offset = target_loc(chan, elem0, scope) # Form the location expression if elem0.indices_value > 0: location = ast.ElemGroup( ast.ExprBinop( '-', i_elem, ast.ExprSingle(ast.ElemNumber(elem0.indices_value)))) else: location = i_elem location = ast.ExprBinop('*', ast.ElemNumber(diff2 + 1), ast.ExprSingle(location)) location = ast.ExprBinop('+', ast.ElemGroup(location), ast.ExprSingle(ast.ElemNumber(offset))) chanend = ast.ElemId(chan.chanend) chanend.symbol = Symbol(chan.chanend, self.chanend_type(chan), None, scope=T_SCOPE_PROC) connid = tab.lookup_connid(chan.name, elem0.index, scope) chanid = ast.ExprSingle(ast.ElemNumber(connid)) begin = elem0.indices_value end = group[1][-1][0].indices_value cond = ast.ExprBinop( '>=', i_elem, ast.ExprSingle(ast.ElemNumber(min(begin, end)))) master = tab.lookup_is_master(chan, elem0, scope) conn = ast.StmtConnect(chanend, chanid, location, self.connect_type(chan, master)) return ast.StmtIf(cond, conn, s) if s else conn
def indices_expr(indices): """ Given a set of indices, return an expression computing their combined value. """ dims = [x.count_value for x in indices] r = None for (i, x) in enumerate(indices): c = reduce(lambda x, y: x * y, dims[i + 1:], 1) c_expr = ast.ExprSingle(ast.ElemNumber(c)) eid = ast.ElemId(x.name) eid.symbol = Symbol(x.name, T_VAL_SINGLE, None, scope=T_SCOPE_PROC) e = ast.ExprBinop('*', eid, c_expr) if c > 1 else ast.ExprSingle(eid) r = e if r == None else ast.ExprBinop('+', ast.ElemGroup(r), e) return r
def create_tree_conn(tab, scope, chan, phase, group_size, base_indices_value, loc_base, loc_diff, connid_min, connid_offset, connid_diff, i_elem): location = ast.ExprBinop( '-', i_elem, ast.ExprSingle(ast.ElemNumber(base_indices_value))) location = ast.ExprBinop( '/', ast.ElemGroup(location), ast.ExprSingle(ast.ElemNumber(group_size))) location = ast.ExprBinop('*', ast.ElemNumber(loc_diff), ast.ExprSingle(ast.ElemGroup(location))) location = ast.ExprBinop('+', ast.ElemNumber(loc_base), ast.ExprSingle(ast.ElemGroup(location))) chanend = ast.ElemId(chan.chanend) chanend.symbol = Symbol(chan.chanend, self.chanend_type(chan), None, scope=T_SCOPE_PROC) elem0 = chan.elems[phase] #connid = ast.ExprBinop('+', i_elem, # ast.ExprSingle(ast.ElemNumber(connid_offset))) connid = ast.ExprBinop('-', i_elem, ast.ExprSingle(ast.ElemNumber(phase))) connid = ast.ExprBinop('rem', ast.ElemGroup(connid), ast.ExprSingle(ast.ElemNumber(group_size))) connid = ast.ExprBinop('*', ast.ElemGroup(connid), ast.ExprSingle(ast.ElemNumber(connid_diff))) connid = ast.ExprBinop('+', ast.ElemGroup(connid), ast.ExprSingle(ast.ElemNumber(connid_min))) master = tab.lookup_is_master(chan, elem0, scope) return ast.StmtConnect(chanend, connid, location, self.connect_type(chan, master))
def form_location(sym, base, offset, compression): """ Given the base id (ElemId), offset (Expr) and compression ratio (integer), produce an expression for a location:: location = (base + (off/comp)) rem NUM_CORES """ assert isinstance(base, ast.Elem) or isinstance(base, ast.Expr) assert isinstance(offset, ast.Expr) if isinstance(base, ast.Expr): base = ast.ElemGroup(base) # Offset loc = offset # Apply compression #if compression > 1: # loc = ast.ExprBinop('/', ast.ElemGroup(loc), # ast.ExprSingle(ast.ElemNumber(compression))) #elem_numcores = ast.ElemId(SYS_NUM_CORES_CONST) #elem_numcores.symbol = sym.lookup(SYS_NUM_CORES_CONST) # Apply 'rem NUM_CORES' to base + (off/comp) loc = ast.ExprSingle( ast.ElemGroup( ast.ExprBinop('+', base, ast.ExprSingle(ast.ElemGroup(loc))))) #ast.ExprBinop('rem', ast.ExprSingle(elem_numcores)) v = EvalExpr().expr(loc) loc = loc if v == None else ast.ExprSingle(ast.ElemNumber(v)) return loc
def create_single_conn(s, chan, scope, i_elem, elem): debug(self.debug, 'New connection for index {}'.format(elem.index)) master = tab.lookup_is_master(chan, elem, scope) if master: location = ast.ExprSingle( ast.ElemNumber( tab.lookup_slave_location(chan.name, elem.index, scope))) else: location = ast.ExprSingle( ast.ElemNumber( tab.lookup_master_location(chan.name, elem.index, scope))) chanend = ast.ElemId(chan.chanend) chanend.symbol = Symbol(chan.chanend, self.chanend_type(chan), None, scope=T_SCOPE_PROC) connid = tab.lookup_connid(chan.name, elem.index, scope) chanid = ast.ExprSingle(ast.ElemNumber(connid)) cond = ast.ExprBinop( '=', i_elem, ast.ExprSingle(ast.ElemNumber(elem.indices_value))) conn = ast.StmtConnect(chanend, chanid, location, self.connect_type(chan, master)) return ast.StmtIf(cond, conn, s) if s != None else conn
def p_expr_binary_relational(self, p): '''expr : elem LT right | elem GT right | elem LE right | elem GE right | elem EQ right | elem NE right''' p[0] = ast.ExprBinop(p[2], p[1], p[3], self.coord(p))
def p_right(self, p): '''right : elem AND right | elem OR right | elem XOR right | elem PLUS right | elem MINUS right | elem REM right | elem DIV right | elem MULT right''' p[0] = ast.ExprBinop(p[2], p[1], p[3], self.coord(p))
def p_expr_binary_arithmetic(self, p): '''expr : elem PLUS right | elem MINUS right | elem MULT right | elem DIV right | elem REM right | elem OR right | elem AND right | elem XOR right | elem LSHIFT right | elem RSHIFT right''' p[0] = ast.ExprBinop(p[2], p[1], p[3], self.coord(p))
def stmt_rep(self, node, l): node.location = l # Calculate total # processes (m) and the next power of two of this (n) node.m = reduce(lambda x, y: x * y.count_value, node.indices, 1) # Determine f and then set l = g(d_1, d_2, ..., d_k, f) k = indices_expr(node.indices) # Add to base (if non-zero) and take modulo if not (isinstance(l, ast.ElemNumber) and l.value == 0): k = ast.ExprBinop('+', l, k) self.stmt(node.stmt, k)
def distribute_stmt(self, m, elem_t, elem_n, elem_m, base, indices, proc_actuals, formals, pcall): """ Create the distribution process body statement. """ # Setup some useful expressions name = self.sig.unique_process_name() elem_x = ast.ElemId('_x') expr_x = ast.ExprSingle(elem_x) expr_t = ast.ExprSingle(elem_t) expr_n = ast.ExprSingle(elem_n) expr_m = ast.ExprSingle(elem_m) elem_base = ast.ElemNumber(base) expr_base = ast.ExprSingle(elem_base) # Replace ocurrances of index variables i with i = f(_t) divisor = m for x in indices: divisor = floor(divisor / x.count_value) # Calculate the index i as a function of _t and the dimensions. e = ast.ExprBinop( 'rem', ast.ElemGroup( ast.ExprBinop('/', elem_t, ast.ExprSingle(ast.ElemNumber(divisor)))), ast.ExprSingle(ast.ElemNumber(x.count_value))) if x.base_value > 0: e = ast.ExprBinop('+', ast.ElemNumber(x.base_value), ast.ExprSingle(ast.ElemGroup(e))) # Then replace it for each ocurrance of i for y in pcall.args: y.accept(SubElem(ast.ElemId(x.name), ast.ElemGroup(e))) d = ast.ExprBinop('+', elem_t, ast.ExprSingle(elem_x)) d = form_location(self.sym, elem_base, d, 1) # Create on the on statement on_stmt = ast.StmtOn( d, ast.StmtPcall(name, [ ast.ExprBinop('+', elem_t, ast.ExprSingle(elem_x)), expr_x, ast.ExprBinop('-', elem_m, ast.ExprSingle(elem_x)) ] + proc_actuals)) on_stmt.location = None # Conditionally recurse {d()|d()} or d() s1 = ast.StmtIf( # if m > n/2 ast.ExprBinop('>', elem_m, ast.ExprSingle(elem_x)), # then ast.StmtPar( [], [ # on id()+t+n/2 do d(t+n/2, n/2, m-n/2, ...) on_stmt, # d(t, n/2, n/2) ast.StmtPcall(name, [expr_t, expr_x, expr_x] + proc_actuals), ], False), # else d(t, n/2, m) ast.StmtPcall(name, [expr_t, expr_x, expr_m] + proc_actuals)) # _x = n/2 ; s1 n_div_2 = ast.ExprBinop('>>', elem_n, ast.ExprSingle(ast.ElemNumber(1))) s2 = ast.StmtSeq([], [ast.StmtAss(elem_x, n_div_2), s1]) # if n = 1 then process() else s1 s3 = ast.StmtIf( ast.ExprBinop('=', elem_n, ast.ExprSingle(ast.ElemNumber(1))), pcall, s2) # Create the local declarations decls = [ast.VarDecl(elem_x.name, T_VAR_SINGLE, None)] s4 = ast.StmtSeq(decls, [s3]) # Create the definition d = ast.ProcDef(name, T_PROC, formals, s4) return d