Ejemplo n.º 1
0
def get_scalar_cvars(pattern):
    cvars = {}
    def maybe_add(access):
        if access.is_scalar() and access.var not in cvars:
            cvars[access.var] = Int(access.var)

    for access in get_accesses(pattern):
        maybe_add(access)
    for decl in pattern.decls:
        for size in decl.sizes:
            if size is not None:
                for access in get_accesses(size):
                    maybe_add(access)

    return cvars
Ejemplo n.º 2
0
 def start(self, args):
     decls = []
     body = []
     # consts = []
     for arg in args:
         if type(arg) == Declaration:
             decls.append(arg)
         elif type(arg) in [AbstractLoop, Assignment]:
             body.append(arg)
         else:
             raise RuntimeError('Unsupported syntax in main program')
     # Add implicit constants that are created when the bounds and steps
     # of loop vars are not explicitly stated
     non_consts = set()
     for decl in decls:
         non_consts.add(decl.name)
     for stmt in body:
         for loop in get_loops(stmt):
             for shape in loop.loop_shapes:
                 non_consts.add(shape.loop_var.var)
     consts_set = set()
     for stmt in body:
         for access in get_accesses(stmt):
             if access.var not in non_consts:
                 consts_set.add(access.var)
     consts = [Const(name) for name in sorted(list(consts_set))]
     return Program(decls, body, consts)
Ejemplo n.º 3
0
def get_int_cvars(pattern, types):
    cvars = {}

    def maybe_add(access):
        name = access.pprint()
        if types.can_be(access.var, 'int') and name not in cvars:
            cvars[name] = Int(name)

    for access in get_accesses(pattern):
        maybe_add(access)
    for decl in pattern.decls:
        for size in decl.sizes:
            if size is not None:
                for access in get_accesses(size):
                    maybe_add(access)

    return cvars
Ejemplo n.º 4
0
def iterate_unique_reference_pairs(program):
    refs = list(get_accesses(program))
    n_refs = len(refs)
    for i in range(0, n_refs):
        for j in range(i, n_refs):
            ref1 = refs[i]
            ref2 = refs[j]
            if ref1.var != ref2.var:
                continue
            if not ref1.is_write and not ref2.is_write:
                continue
            yield (ref1, ref2)
Ejemplo n.º 5
0
    def try_once():
        random_pattern = replace_constant_variables_blindly(pattern, var_map)
        cvars = get_scalar_cvars(random_pattern)
        accesses = get_accesses(random_pattern)
        cloned_var_map = var_map.clone()

        # Set array sizes in var map
        for decl in random_pattern.decls:
            for dimension in range(decl.n_dimensions):
                size = decl.sizes[dimension]
                if size is not None:
                    dim_var = dimension_var(decl.name, dimension)
                    # TODO: we don't really need min
                    cloned_var_map.set_min(dim_var, 0)
                    # TODO: maybe allow more room for the max
                    cloned_var_map.set_max(dim_var, size)

        index_constraints = generate_index_constraints(accesses,
                                                       cvars,
                                                       cloned_var_map)

        loop_shape_constraints = []
        for loop in get_loops(random_pattern):
            loop_shape_constraints += generate_loop_shape_constraints(loop.loop_shapes,
                                                                      cvars,
                                                                      cloned_var_map)

        bound_constraints = generate_bound_constraints(random_pattern.decls, cvars, cloned_var_map)

        l.debug('Index constraints:\n' + '\n'.join(map(str, index_constraints)))
        l.debug('Loop shape constraints:\n' + '\n'.join(map(str, loop_shape_constraints)))
        l.debug('Bound constraints:\n' + '\n'.join(map(str, bound_constraints)))

        assert(len(index_constraints) > 0)
        invert_index_constraints = Not(And(index_constraints))

        constraints = [invert_index_constraints] + loop_shape_constraints + bound_constraints

        solver = Solver()
        solver.set('timeout', 10000)
        solver.add(constraints)
        status = solver.check()
        if status != unsat:
            l.debug(f'Constraints are not unsatisfiable ({status}). '
                    'May result in index out of bound')
            l.debug('Constraints:\n' + '\n'.join(map(str, constraints)))
            if status == sat:
                l.debug(f'Model:\n{solver.model()}')
            return None

        constraints = index_constraints + loop_shape_constraints + bound_constraints
        solver = Solver()
        solver.set('timeout', 10000)
        solver.add(constraints)
        status = solver.check()
        if status != sat:
            l.debug(f'Constraints are not satisfiable ({status}). '
                    'May result in no iterations')
            l.debug('\n'.join(map(str, constraints)))
            return None

        bounds = determine_array_access_bounds(random_pattern.decls,
                                               accesses, cvars,
                                               constraints,
                                               cloned_var_map, l)
        if bounds is None:
            return None

        # assign types once we're sure it's a valid program
        nonlocal types
        if types is None:
            types = TypeAssignment()
        assign_types(random_pattern, types)
        return Instance(random_pattern, bounds)