def fill_hole_with_same_name(): # Holes with the same name will be filled with the same choice. # # The name "_" (an underscore) is special. Two "_" are always # considered to be different. As a result, two "_" holes may be # filled with different options. # # Holes with different names may be different (but can also be the # same by random choice). # # In this code, all x1 holes should look the same. The x2 hole may # be anything. The two _ holes may be anything and don't have to # be the same. code = """ declare A[]; declare B[]; declare C[]; declare D[]; for [i] { `x1`[i] = `_`[i]; `x1`[i] = `_`[i]; `x1`[i] = `x2`[i]; } """ skeleton = parse_skeleton(code) print(skeleton.pprint()) parameters = PopulateParameters() parameters.add('_', [Var('A'), Var('B'), Var('C'), Var('D')]) filled_skeleton = populate_name(skeleton, parameters.populate) print(filled_skeleton.pprint())
def fill_name_hole(): # A name hole is surrounded by backticks # It has two portions: # * its name # * its family name # For example, the hole x1:X has name x1 and family X code = """ declare A[]; declare B[]; declare C[]; declare D[]; for [i] { `x1:X`[i] = `x2:X`[i]; `y1:Y`[i] = `y2:Y`[i]; } """ skeleton = parse_skeleton(code) print(skeleton.pprint()) # For each family, we add the possible options to fill that hole. # Name holes are filled with variables, so we need to provide # Var nodes as options. parameters = PopulateParameters() parameters.add('X', [Var('A'), Var('B')]) parameters.add('Y', [Var('C'), Var('D')]) filled_skeleton = populate_name(skeleton, parameters.populate) print(filled_skeleton.pprint())
def create_full_skeleton(): code = """ declare A[]; declare B[]; declare C[]; for [i] { $_$ $_$ } """ skeleton = parse_skeleton(code) print(skeleton.pprint()) stmt_codes = [ 'A[i] = 1;', 'A[i] = B[i] + C[i];', 'A[i] = 5 * D[i];', ] parameters = PopulateParameters() parameters.add('_', [parse_stmt(code) for code in stmt_codes]) filled_skeleton = populate_stmt(skeleton, parameters.populate) print(filled_skeleton.pprint()) return filled_skeleton
def fill_hole_with_default_family(): # The family name is optional. It defaults to the family named "_" # (an underscore). code = """ declare A[]; declare B[]; declare C[]; declare D[]; for [i] { `x1`[i] = `x2`[i]; `y1:_`[i] = `y2:_`[i]; } """ skeleton = parse_skeleton(code) print(skeleton.pprint()) # x1, x2, y1, and y2 all belonw to family _. parameters = PopulateParameters() parameters.add('_', [Var('A'), Var('B'), Var('C'), Var('D')]) filled_skeleton = populate_name(skeleton, parameters.populate) print(filled_skeleton.pprint())
from pattern import parse_str as parse_pattern from populator import PopulateParameters, populate_name matmul_code = """ declare A[][]; declare B[][]; declare C[][]; for [i, j, k] { A[`x:index`][`y:index`] = A[`x:index`][`y:index`] + `_:array`[`x:index`][k] * `_:array`[k][`y:index`]; } """ skeleton = parse_skeleton(matmul_code) print(skeleton.pprint()) array_choices = [Var('A'), Var('B'), Var('C')] index_choices = [Var('i'), Var('j')] populator = PopulateParameters() populator.add('array', array_choices) populator.add('index', index_choices) maybe_pattern = populate_name(skeleton.clone(), populator.populate) maybe_pattern_code = maybe_pattern.pprint() pattern = parse_pattern(maybe_pattern_code) print(pattern.pprint())
# For index choices, we want either something like A[i][j] or A[j][i], # but not A[i][i] or A[j][j]. Basically, we are interested in the # permutation of the possible choices. The space should be [2, 1], # because when we fill the first hole, we have two choices from {i, # j}, but for the second hole, we only have one choice left. index_choices = [Var('i'), Var('j')] index_choice_space = [2, 1] # The ChoiceFactoryEnumerator then can be used to generate the sampling functions as follows for array_choice_factory in ChoiceFactoryEnumerator( array_choice_space).enumerate(): for index_choice_factory in ChoiceFactoryEnumerator( index_choice_space).enumerate(): populator = PopulateParameters() populator.add( 'array', array_choices, choice_function=array_choice_factory.create_choice_function()) # Note that is_finite=True. Once we already pick a choice from the space, # we remove it from the space. Permutation can be viewed like this. populator.add( 'index', index_choices, is_finite=True, choice_function=index_choice_factory.create_choice_function()) maybe_pattern = populate_name(skeleton.clone(), populator.populate) maybe_pattern_code = maybe_pattern.pprint() pattern = parse_pattern(maybe_pattern_code) print(pattern.pprint())
from skeleton import parse_str as parse_skeleton from skeleton_ast import Op from populator import PopulateParameters, populate_op # An operator hole is surrounded by @. # The usage is the same as the name hole, except where it may appear in the AST. code = """ declare A[]; declare B[]; declare C[]; for [i] { A[i] = A[i] @_@ B[i] @_@ C[i]; } """ skeleton = parse_skeleton(code) print(skeleton.pprint()) # Op nodes as options. parameters = PopulateParameters() parameters.add('_', [Op('+'), Op('-'), Op('*'), Op('/')]) filled_skeleton = populate_op(skeleton, parameters.populate) print(filled_skeleton.pprint())
parse_expr_str as parse_expr from populator import PopulateParameters, populate_expr # An expression hole is surrounded by #. # The usage is the same as the name hole, except where it may appear in the AST. code = """ declare A[]; declare B[]; declare C[]; for [i] { A[i] = #_#; } """ skeleton = parse_skeleton(code) print(skeleton.pprint()) # Expr nodes as options. expr_codes = [ 'A[i] * B[i]', 'B[i] + C[i]', 'C[i] - D[i]', ] parameters = PopulateParameters() parameters.add('_', [parse_expr(code) for code in expr_codes]) filled_skeleton = populate_expr(skeleton, parameters.populate) print(filled_skeleton.pprint())
from populator import PopulateParameters, populate_stmt # A statement hole is surrounded by $. # The usage is the same as the name hole, except where it may appear in the AST. code = """ declare A[]; declare B[]; declare C[]; for [i] { $_$ $_$ } """ skeleton = parse_skeleton(code) print(skeleton.pprint()) # Statement nodes as options. stmt_codes = [ 'A[i] = 1;', 'A[i] = B[i] + C[i];', 'A[i] = 5 * D[i];', ] parameters = PopulateParameters() parameters.add('_', [parse_stmt(code) for code in stmt_codes]) filled_skeleton = populate_stmt(skeleton, parameters.populate) print(filled_skeleton.pprint())