def test_ccode_Declaration(): i = symbols('i', integer=True) var1 = Variable(i, type=Type.from_expr(i)) dcl1 = Declaration(var1) assert ccode(dcl1) == 'int i' var2 = Variable(x, type=float32, attrs={value_const}) dcl2a = Declaration(var2) assert ccode(dcl2a) == 'const float x' dcl2b = var2.as_Declaration(value=pi) assert ccode(dcl2b) == 'const float x = M_PI' var3 = Variable(y, type=Type('bool')) dcl3 = Declaration(var3) printer = C89CodePrinter() assert 'stdbool.h' not in printer.headers assert printer.doprint(dcl3) == 'bool y' assert 'stdbool.h' in printer.headers u = symbols('u', real=True) ptr4 = Pointer.deduced(u, attrs={pointer_const, restrict}) dcl4 = Declaration(ptr4) assert ccode(dcl4) == 'double * const restrict u' var5 = Variable(x, Type('__float128'), attrs={value_const}) dcl5a = Declaration(var5) assert ccode(dcl5a) == 'const __float128 x' var5b = Variable(var5.symbol, var5.type, pi, attrs=var5.attrs) dcl5b = Declaration(var5b) assert ccode(dcl5b) == 'const __float128 x = M_PI'
def test_Declaration(): u = symbols('u', real=True) vu = Variable(u, type=Type.from_expr(u)) assert Declaration(vu).variable.type == real vn = Variable(n, type=Type.from_expr(n)) assert Declaration(vn).variable.type == integer lt = StrictLessThan(vu, vn) assert isinstance(lt, StrictLessThan) vuc = Variable(u, Type.from_expr(u), value=3.0, attrs={value_const}) assert value_const in vuc.attrs assert pointer_const not in vuc.attrs decl = Declaration(vuc) assert decl.variable == vuc assert isinstance(decl.variable.value, Float) assert decl.variable.value == 3.0 assert decl.func(*decl.args) == decl assert vuc.as_Declaration() == decl assert vuc.as_Declaration(value=None, attrs=None) == Declaration(vu) vy = Variable(y, type=integer, value=3) decl2 = Declaration(vy) assert decl2.variable == vy assert decl2.variable.value == Integer(3) vi = Variable(i, type=Type.from_expr(i), value=3.0) decl3 = Declaration(vi) assert decl3.variable.type == integer assert decl3.variable.value == 3.0 raises(ValueError, lambda: Declaration(vi, 42))
def test_ccode_Declaration(): i = symbols("i", integer=True) var1 = Variable(i, type=Type.from_expr(i)) dcl1 = Declaration(var1) assert ccode(dcl1) == "int i" var2 = Variable(x, type=float32, attrs={value_const}) dcl2a = Declaration(var2) assert ccode(dcl2a) == "const float x" dcl2b = var2.as_Declaration(value=pi) assert ccode(dcl2b) == "const float x = M_PI" var3 = Variable(y, type=Type("bool")) dcl3 = Declaration(var3) printer = C89CodePrinter() assert "stdbool.h" not in printer.headers assert printer.doprint(dcl3) == "bool y" assert "stdbool.h" in printer.headers u = symbols("u", real=True) ptr4 = Pointer.deduced(u, attrs={pointer_const, restrict}) dcl4 = Declaration(ptr4) assert ccode(dcl4) == "double * const restrict u" var5 = Variable(x, Type("__float128"), attrs={value_const}) dcl5a = Declaration(var5) assert ccode(dcl5a) == "const __float128 x" var5b = Variable(var5.symbol, var5.type, pi, attrs=var5.attrs) dcl5b = Declaration(var5b) assert ccode(dcl5b) == "const __float128 x = M_PI"
def test_Type_eq(): t1 = Type('t1') t2 = Type('t2') assert t1 != t2 assert t1 == t1 and t2 == t2 t1b = Type('t1') assert t1 == t1b assert t2 != t1b
def test_Type(): t = Type('MyType') assert len(t.args) == 1 assert t.name == String('MyType') assert str(t) == 'MyType' assert repr(t) == "Type(String('MyType'))" assert Type(t) == t assert t.func(*t.args) == t t1 = Type('t1') t2 = Type('t2') assert t1 != t2 assert t1 == t1 and t2 == t2 t1b = Type('t1') assert t1 == t1b assert t2 != t1b
def test_Variable(): v = Variable(x, type_=Type('real')) assert v.symbol == x assert v.type == real assert v.value_const == False w = Variable(y, {value_const}, f32) assert w.symbol == y assert w.type == f32 assert w.value_const v_n = Variable(n, type_=Type.from_expr(n)) assert v_n.type == integer v_i = Variable(i, type_=Type.from_expr(n)) assert v_i.type == integer a_i = Variable.deduced(i) assert a_i.type == integer
def test_using(): v = Type("std::vector") u1 = using(v) assert cxxcode(u1) == "using std::vector" u2 = using(v, "vec") assert cxxcode(u2) == "using vec = std::vector"
def test_using(): v = Type('std::vector') u1 = using(v) assert cxxcode(u1) == 'using std::vector' u2 = using(v, 'vec') assert cxxcode(u2) == 'using vec = std::vector'
def test_Type__from_expr(): assert Type.from_expr(i) == integer u = symbols('u', real=True) assert Type.from_expr(u) == real assert Type.from_expr(n) == integer assert Type.from_expr(3) == integer assert Type.from_expr(3.0) == real assert Type.from_expr(3 + 1j) == complex_ raises(ValueError, lambda: Type.from_expr(sum))
def test_Type__from_expr(): assert Type.from_expr(i) == integer u = symbols('u', real=True) assert Type.from_expr(u) == real assert Type.from_expr(n) == integer assert Type.from_expr(3) == integer assert Type.from_expr(3.0) == real assert Type.from_expr(3+1j) == complex_ raises(ValueError, lambda: Type.from_expr(sum))
def test_Pointer(): p = Pointer(x) assert p.symbol == x assert p.type == None assert not p.value_const assert not p.pointer_const u = symbols('u', real=True) py = Pointer(u, {value_const, pointer_const}, Type.from_expr(u)) assert py.symbol is u assert py.type == real assert py.value_const assert py.pointer_const
def test_Variable(): v = Variable(x, type=real) assert v == Variable(v) assert v == Variable('x', type=real) assert v.symbol == x assert v.type == real assert value_const not in v.attrs assert v.func(*v.args) == v assert str(v) == 'Variable(x, type=real)' w = Variable(y, f32, attrs={value_const}) assert w.symbol == y assert w.type == f32 assert value_const in w.attrs assert w.func(*w.args) == w v_n = Variable(n, type=Type.from_expr(n)) assert v_n.type == integer assert v_n.func(*v_n.args) == v_n v_i = Variable(i, type=Type.from_expr(n)) assert v_i.type == integer assert v_i != v_n a_i = Variable.deduced(i) assert a_i.type == integer assert Variable.deduced(Symbol('x', real=True)).type == real assert a_i.func(*a_i.args) == a_i v_n2 = Variable.deduced(n, value=3.5, cast_check=False) assert v_n2.func(*v_n2.args) == v_n2 assert abs(v_n2.value - 3.5) < 1e-15 raises(ValueError, lambda: Variable.deduced(n, value=3.5, cast_check=True)) v_n3 = Variable.deduced(n) assert v_n3.type == integer assert str(v_n3) == 'Variable(n, type=integer)' assert Variable.deduced(z, value=3).type == integer assert Variable.deduced(z, value=3.0).type == real assert Variable.deduced(z, value=3.0 + 1j).type == complex_
def test_Variable(): v = Variable(x, type=real) assert v == Variable(v) assert v == Variable('x', type=real) assert v.symbol == x assert v.type == real assert value_const not in v.attrs assert v.func(*v.args) == v assert str(v) == 'Variable(x, type=real)' w = Variable(y, f32, attrs={value_const}) assert w.symbol == y assert w.type == f32 assert value_const in w.attrs assert w.func(*w.args) == w v_n = Variable(n, type=Type.from_expr(n)) assert v_n.type == integer assert v_n.func(*v_n.args) == v_n v_i = Variable(i, type=Type.from_expr(n)) assert v_i.type == integer assert v_i != v_n a_i = Variable.deduced(i) assert a_i.type == integer assert Variable.deduced(Symbol('x', real=True)).type == real assert a_i.func(*a_i.args) == a_i v_n2 = Variable.deduced(n, value=3.5, cast_check=False) assert v_n2.func(*v_n2.args) == v_n2 assert abs(v_n2.value - 3.5) < 1e-15 raises(ValueError, lambda: Variable.deduced(n, value=3.5, cast_check=True)) v_n3 = Variable.deduced(n) assert v_n3.type == integer assert str(v_n3) == 'Variable(n, type=integer)' assert Variable.deduced(z, value=3).type == integer assert Variable.deduced(z, value=3.0).type == real assert Variable.deduced(z, value=3.0+1j).type == complex_
def test_Declaration(): u = symbols('u', real=True) vu = Variable(u, type_=Type.from_expr(u)) assert Declaration(vu).variable.type == real vn = Variable(n, type_=Type.from_expr(n)) assert Declaration(vn).variable.type == integer vuc = Variable(u, {value_const}, Type.from_expr(u)) decl = Declaration(vuc, 3.0) assert decl.variable == vuc assert isinstance(decl.value, Float) assert decl.value == 3.0 vy = Variable(y, type_=integer) decl2 = Declaration(vy, 3) assert decl2.variable == vy assert decl2.value is Integer(3) vi = Variable(i, type_=Type.from_expr(i)) decl3 = Declaration(vi, 3.0) assert decl3.variable.type == integer assert decl3.value == 3.0 decl4 = raises(ValueError, lambda: Declaration.deduced(n, 3.5, cast=True))
def test_Pointer(): p = Pointer(x) assert p.symbol == x assert p.type == untyped assert value_const not in p.attrs assert pointer_const not in p.attrs assert p.func(*p.args) == p u = symbols('u', real=True) pu = Pointer(u, type=Type.from_expr(u), attrs={value_const, pointer_const}) assert pu.symbol is u assert pu.type == real assert value_const in pu.attrs assert pointer_const in pu.attrs assert pu.func(*pu.args) == pu i = symbols('i', integer=True) deref = pu[i] assert deref.indices == (i, )
def test_Pointer(): p = Pointer(x) assert p.symbol == x assert p.type == untyped assert value_const not in p.attrs assert pointer_const not in p.attrs assert p.func(*p.args) == p u = symbols('u', real=True) pu = Pointer(u, type=Type.from_expr(u), attrs={value_const, pointer_const}) assert pu.symbol is u assert pu.type == real assert value_const in pu.attrs assert pointer_const in pu.attrs assert pu.func(*pu.args) == pu i = symbols('i', integer=True) deref = pu[i] assert deref.indices == (i,)
def test_ccode_Type(): assert ccode(Type("float")) == "float" assert ccode(intc) == "int"
def gen_function(self, kernel_name, kernel_arg_type_name): main_block = [] main_block.append( Comment( "Output iteration space %s reduced to %s iteration spaces" % (self._max_shape, len(self._indexes)))) # dereference all symbols that are not indexed dereference = [ symbol for symbol in self._symbol_indexes if not self._symbol_indexes[symbol] ] for expr_state in self._expr_states: free_symbols = [ symbol for symbol in expr_state.expr.free_symbols if not symbol in self._temporaries ] # create substitutions for symbols that are indexed subs = [(symbol, indexed_symbol(symbol, [ self._indexes[idx][1] for idx in self._symbol_indexes[symbol] ], [ self._indexes[idx][0] for idx in self._symbol_indexes[symbol] ])) for symbol in free_symbols if self._symbol_indexes[symbol]] # indexed results. non indexed temps if not expr_state.is_intermediate: main_block.append( Comment("Produce output symbol %s" % expr_state.symbol)) res_symbol = IndexedBase( expr_state.symbol, shape=tuple(tuple(index[1] for index in self._indexes))) res_symbol = res_symbol[tuple(index[0] for index in self._indexes)] else: main_block.append( Comment("Produce intermediate symbol %s" % expr_state.symbol)) res_symbol = expr_state.symbol main_block.append( Assignment(res_symbol, expr_state.expr.subs(subs))) # create all the for loops def func(block, idx): return [ VarFor(Declaration(Variable(Symbol(idx[0]), type=uint32)), VarRange(idx[2][0], idx[2][1], Integer(1)), block) ] for_block = reduce(func, self._indexes[::-1], main_block)[0] # Create the initial code with args assignments and paralellization calcluation ast = self.setup_codegen() # declare temporaries ast.extend([ Declaration(Variable(symbol, type=int32)) for symbol in self._temporaries ]) ast.append(for_block) ast.append(FunctionCall("gap_waitbarrier", (Integer(0), ))) # create function definition func_def = FunctionDefinition( VOID, kernel_name, [Pointer("Args", type=Type(kernel_arg_type_name))], ast) # generate code return ccode(func_def, contract=False, dereference=dereference, user_functions=CFUNC_DEFS, type_mappings=TYPE_MAPPINGS)
""" AST nodes specific to the C family of languages """ from sympy.core.basic import Basic from sympy.core.compatibility import string_types from sympy.core.containers import Tuple from sympy.core.sympify import sympify from sympy.codegen.ast import Attribute, Declaration, Node, String, Token, Type, none, FunctionCall void = Type('void') restrict = Attribute('restrict') # guarantees no pointer aliasing volatile = Attribute('volatile') static = Attribute('static') def alignof(arg): """ Generate of FunctionCall instance for calling 'alignof' """ return FunctionCall( 'alignof', [String(arg) if isinstance(arg, string_types) else arg]) def sizeof(arg): """ Generate of FunctionCall instance for calling 'sizeof' Examples ======== >>> from sympy.codegen.ast import real >>> from sympy.codegen.cnodes import sizeof
def transform_var_decl(self, node): """Transformation Function for Variable Declaration Used to create nodes for variable declarations and assignments with values or function call for the respective nodes in the clang AST Returns ======= A variable node as Declaration, with the given value or 0 if the value is not provided Raises ====== NotImplementedError : if called for data types not currently implemented Notes ===== This function currently only supports basic Integer and Float data types """ try: children = node.get_children() child = next(children) #ignoring namespace and type details for the variable while child.kind == cin.CursorKind.NAMESPACE_REF: child = next(children) while child.kind == cin.CursorKind.TYPE_REF: child = next(children) val = self.transform(child) # List in case of variable assignment, # FunctionCall node in case of a function call if (child.kind == cin.CursorKind.INTEGER_LITERAL or child.kind == cin.CursorKind.UNEXPOSED_EXPR): if (node.type.kind == cin.TypeKind.INT): type = IntBaseType(String('integer')) # when only one decl_ref_expr is assigned # e.g., int b = a; if isinstance(val, str): value = Symbol(val) # e.g., int b = true; elif isinstance(val, bool): value = Integer(0) if val == False else Integer(1) # when val is integer or character literal # e.g., int b = 1; or int b = 'a'; elif isinstance(val, (Integer, int, Float, float)): value = Integer(val) # when val is combination of both of the above # but in total only two nodes on rhs # e.g., int b = a * 1; else: value = val elif (node.type.kind == cin.TypeKind.FLOAT): type = FloatBaseType(String('real')) # e.g., float b = a; if isinstance(val, str): value = Symbol(val) # e.g., float b = true; elif isinstance(val, bool): value = Float(0.0) if val == False else Float(1.0) # e.g., float b = 1.0; elif isinstance(val, (Integer, int, Float, float)): value = Float(val) # e.g., float b = a * 1.0; else: value = val elif (node.type.kind == cin.TypeKind.BOOL): type = Type(String('bool')) # e.g., bool b = a; if isinstance(val, str): value = Symbol(val) # e.g., bool b = 1; elif isinstance(val, (Integer, int, Float, float)): value = sympify(bool(val)) # e.g., bool b = a * 1; else: value = val else: raise NotImplementedError("Only bool, int " \ "and float are supported") elif (child.kind == cin.CursorKind.CALL_EXPR): return Variable( node.spelling ).as_Declaration( value = val ) # when val is combination of more than two expr and # integer(or float) elif (child.kind == cin.CursorKind.BINARY_OPERATOR): if (node.type.kind == cin.TypeKind.INT): type = IntBaseType(String('integer')) elif (node.type.kind == cin.TypeKind.FLOAT): type = FloatBaseType(String('real')) elif (node.type.kind == cin.TypeKind.BOOL): type = Type(String('bool')) else: raise NotImplementedError("Only bool, int " \ "and float are supported") value = val elif (child.kind == cin.CursorKind.CXX_BOOL_LITERAL_EXPR): if (node.type.kind == cin.TypeKind.INT): type = IntBaseType(String('integer')) value = Integer(val) elif (node.type.kind == cin.TypeKind.FLOAT): type = FloatBaseType(String('real')) value = Float(val) elif (node.type.kind == cin.TypeKind.BOOL): type = Type(String('bool')) value = sympify(val) else: raise NotImplementedError("Only bool, int " \ "and float are supported") else: raise NotImplementedError() except StopIteration: if (node.type.kind == cin.TypeKind.INT): type = IntBaseType(String('integer')) value = Integer(0) elif (node.type.kind == cin.TypeKind.FLOAT): type = FloatBaseType(String('real')) value = Float(0.0) elif (node.type.kind == cin.TypeKind.BOOL): type = Type(String('bool')) value = false else: raise NotImplementedError("Only bool, int " \ "and float are supported") return Variable( node.spelling ).as_Declaration( type = type, value = value )
# along with this program. If not, see <https://www.gnu.org/licenses/>. import logging from functools import reduce from sympy import Range from sympy.codegen.ast import (Assignment, Declaration, For, Pointer, Token, Type, Variable, pointer_const, untyped, value_const) from sympy.printing.ccode import C99CodePrinter from sympy.printing.precedence import precedence from sympy.tensor.indexed import Indexed LOG = logging.getLogger("nntool." + __name__) VOID = Type("void") #pylint: disable=no-init class AssignmentEx(Assignment): @classmethod def _check_args(cls, lhs, rhs): if isinstance(lhs, Declaration): super(AssignmentEx, cls)._check_args(lhs.variable, rhs) else: super(AssignmentEx, cls)._check_args(lhs, rhs) #pylint: disable=no-init class IndexedEx(Indexed): def _sympystr(self, p):
def test_Type(): t = Type('MyType') assert t.name == 'MyType' assert str(t) == 'MyType' assert repr(t) == "Type(name=MyType)"
from sympy.codegen.ast import ( Attribute, Declaration, Node, String, Token, Type, none, FunctionCall, ) from sympy.core.basic import Basic from sympy.core.containers import Tuple from sympy.core.sympify import sympify void = Type("void") restrict = Attribute("restrict") # guarantees no pointer aliasing volatile = Attribute("volatile") static = Attribute("static") def alignof(arg): """ Generate of FunctionCall instance for calling 'alignof' """ return FunctionCall("alignof", [String(arg) if isinstance(arg, str) else arg]) def sizeof(arg): """ Generate of FunctionCall instance for calling 'sizeof'
class CXX11CodePrinter(_CXXCodePrinterBase, C99CodePrinter): standard = 'C++11' reserved_words = set(reserved['C++11']) type_mappings = dict( chain( CXX98CodePrinter.type_mappings.items(), { Type('int8'): ('int8_t', {'cstdint'}), Type('int16'): ('int16_t', {'cstdint'}), Type('int32'): ('int32_t', {'cstdint'}), Type('int64'): ('int64_t', {'cstdint'}), Type('uint8'): ('uint8_t', {'cstdint'}), Type('uint16'): ('uint16_t', {'cstdint'}), Type('uint32'): ('uint32_t', {'cstdint'}), Type('uint64'): ('uint64_t', {'cstdint'}), Type('complex64'): ('std::complex<float>', {'complex'}), Type('complex128'): ('std::complex<double>', {'complex'}), Type('bool'): ('bool', None), }.items())) def _print_using(self, expr): if expr.alias == none: return super(CXX11CodePrinter, self)._print_using(expr) else: return 'using %(alias)s = %(type)s' % expr.kwargs( apply=self._print)
class CXX11CodePrinter(_CXXCodePrinterBase, C99CodePrinter): standard = 'C++11' reserved_words = set(reserved['C++11']) type_mappings = dict(chain( CXX98CodePrinter.type_mappings.items(), { Type('int8'): ('int8_t', {'cstdint'}), Type('int16'): ('int16_t', {'cstdint'}), Type('int32'): ('int32_t', {'cstdint'}), Type('int64'): ('int64_t', {'cstdint'}), Type('uint8'): ('uint8_t', {'cstdint'}), Type('uint16'): ('uint16_t', {'cstdint'}), Type('uint32'): ('uint32_t', {'cstdint'}), Type('uint64'): ('uint64_t', {'cstdint'}), Type('complex64'): ('std::complex<float>', {'complex'}), Type('complex128'): ('std::complex<double>', {'complex'}), Type('bool'): ('bool', None), }.items() ))
def test_ccode_Type(): assert ccode(Type('float')) == 'float' assert ccode(intc) == 'int'
class CXX11CodePrinter(_CXXCodePrinterBase, C99CodePrinter): standard = "C++11" reserved_words = set(reserved["C++11"]) type_mappings = dict( chain( CXX98CodePrinter.type_mappings.items(), { Type("int8"): ("int8_t", {"cstdint"}), Type("int16"): ("int16_t", {"cstdint"}), Type("int32"): ("int32_t", {"cstdint"}), Type("int64"): ("int64_t", {"cstdint"}), Type("uint8"): ("uint8_t", {"cstdint"}), Type("uint16"): ("uint16_t", {"cstdint"}), Type("uint32"): ("uint32_t", {"cstdint"}), Type("uint64"): ("uint64_t", {"cstdint"}), Type("complex64"): ("std::complex<float>", {"complex"}), Type("complex128"): ("std::complex<double>", {"complex"}), Type("bool"): ("bool", None), }.items(), )) def _print_using(self, expr): if expr.alias == none: return super(CXX11CodePrinter, self)._print_using(expr) else: return "using %(alias)s = %(type)s" % expr.kwargs( apply=self._print)