From 77597c1f18921922982f33c5a793f46da3df3e4c Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Sun, 11 Mar 2018 17:16:58 -0500 Subject: [PATCH 1/2] Add insn-to-statement script --- insn-to-statement.sh | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 insn-to-statement.sh diff --git a/insn-to-statement.sh b/insn-to-statement.sh new file mode 100644 index 0000000..84e67ee --- /dev/null +++ b/insn-to-statement.sh @@ -0,0 +1,7 @@ +set -x +set -e +sed -i s/Instruction/Statement/g $(git ls-files | grep -v insn-to-statement.sh) +sed -i s/instruction/statement/g $(git ls-files | grep -v insn-to-statement.sh) +sed -i s/INSTRUCTION/STATEMENT/g $(git ls-files | grep -v insn-to-statement.sh) +sed -i s/insn/stmt/g $(git ls-files | grep -v insn-to-statement.sh) +#patch -p1 < ./stmt-compat-fixes.patch -- GitLab From eb349264879a173625f9edd34752fb77fa6353fb Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Sun, 11 Mar 2018 17:18:14 -0500 Subject: [PATCH 2/2] Apply instruction-to-statement rename --- dagrt/codegen/analysis.py | 68 +++++----- dagrt/codegen/codegen_base.py | 10 +- dagrt/codegen/dag_ast.py | 76 +++++------ dagrt/codegen/data.py | 92 ++++++------- dagrt/codegen/fortran.py | 2 +- dagrt/codegen/python.py | 6 +- dagrt/codegen/transform.py | 172 ++++++++++++------------ dagrt/exec_numpy.py | 76 +++++------ dagrt/language.py | 244 +++++++++++++++++----------------- dagrt/transform.py | 8 +- examples/adaptive_rk.py | 2 +- test/test_ast.py | 10 +- test/test_builtins.py | 8 +- test/test_code_builder.py | 16 +-- test/test_codegen.py | 10 +- test/test_codegen_fortran.py | 4 +- test/test_codegen_python.py | 32 ++--- test/utils.py | 36 ++--- 18 files changed, 436 insertions(+), 436 deletions(-) diff --git a/dagrt/codegen/analysis.py b/dagrt/codegen/analysis.py index 5b8789c..2d4e40c 100644 --- a/dagrt/codegen/analysis.py +++ b/dagrt/codegen/analysis.py @@ -38,40 +38,40 @@ def verify_phase_transitions(phases, errors): """ Ensure that phases referenced by PhaseTransition exist. - :arg instructions: A set of instructions to verify + :arg statements: A set of statements to verify :arg phases: A map from phase names to phases :arg errors: An error list to which new errors get appended """ phase_names = [key for key in phases.keys()] for phase in six.itervalues(phases): - for inst in phase.instructions: + for inst in phase.statements: if not isinstance(inst, PhaseTransition): continue if inst.next_phase not in phase_names: errors.append( - "Phase \"{0}\" referenced by instruction \"{1}:{2}\" not found" + "Phase \"{0}\" referenced by statement \"{1}:{2}\" not found" .format(inst.next_phase, phase, inst)) def verify_all_dependencies_exist(phases, errors): """ - Ensure that all instruction dependencies exist. + Ensure that all statement dependencies exist. - :arg instructions: A set of instructions to verify + :arg statements: A set of statements to verify :arg phases: A map from phase names to phases :arg errors: An error list to which new errors get appended """ ids = set(inst.id for phase in six.itervalues(phases) - for inst in phase.instructions) + for inst in phase.statements) - # Check instructions + # Check statements for phase in six.itervalues(phases): - for inst in phase.instructions: + for inst in phase.statements: deps = set(inst.depends_on) if not deps <= ids: errors.extend( - ["Dependency \"{0}\" referenced by instruction \"{1}\" not found" + ["Dependency \"{0}\" referenced by statement \"{1}\" not found" .format(dep_name, inst) for dep_name in deps - ids]) # Check phases. @@ -84,15 +84,15 @@ def verify_all_dependencies_exist(phases, errors): phase_name)]) -def verify_no_circular_dependencies(instructions, errors): +def verify_no_circular_dependencies(statements, errors): """ - Ensure that there are no circular dependencies among the instructions. + Ensure that there are no circular dependencies among the statements. - :arg instructions: A set of instructions to verify + :arg statements: A set of statements to verify :arg errors: An error list to which new errors get appended """ - id_to_instruction = dict((inst.id, inst) for inst in instructions) - stack = list(instructions) + id_to_statement = dict((inst.id, inst) for inst in statements) + stack = list(statements) visiting = set() visited = set() while stack: @@ -104,36 +104,36 @@ def verify_no_circular_dependencies(instructions, errors): if neighbor in visiting: errors.append("Circular dependency chain found") return - stack.append(id_to_instruction[neighbor]) + stack.append(id_to_statement[neighbor]) else: if top.id in visiting: visiting.remove(top.id) stack.pop() -def verify_single_definition_cond_rule(instructions, errors): +def verify_single_definition_cond_rule(statements, errors): """ Verify that variables are never redefined. - :arg instructions: A set of instructions to verify + :arg statements: A set of statements to verify :arg errors: An error list to which new errors get appended """ cond_variables = {} - for instruction in instructions: - for varname in instruction.get_written_variables(): + for statement in statements: + for varname in statement.get_written_variables(): if not varname.startswith(""): continue if varname not in cond_variables: - cond_variables[varname] = [instruction] + cond_variables[varname] = [statement] else: - cond_variables[varname].append(instruction) + cond_variables[varname].append(statement) import six for varname, insts in six.iteritems(cond_variables): if len(insts) > 1: errors.append( - "Conditional variable \"{0}\" defined by multiple instructions: {1}" + "Conditional variable \"{0}\" defined by multiple statements: {1}" .format(varname, ", ".join(_quote(str(inst)) for inst in insts))) @@ -155,12 +155,12 @@ def verify_code(code): # malformed code. verify_all_dependencies_exist(code.phases, errors) for phase in six.itervalues(code.phases): - verify_no_circular_dependencies(phase.instructions, errors) + verify_no_circular_dependencies(phase.statements, errors) verify_phase_transitions(code.phases, errors) for phase in six.itervalues(code.phases): - verify_single_definition_cond_rule(phase.instructions, errors) + verify_single_definition_cond_rule(phase.statements, errors) except Exception as e: # Ensure there is at least one error to report. @@ -206,12 +206,12 @@ def collect_function_names_from_dag(dag, no_expressions=False): result.update(fnc(expr)) return expr for phase in six.itervalues(dag.phases): - for insn in phase.instructions: - if isinstance(insn, AssignFunctionCall): - result.add(insn.function_id) + for stmt in phase.statements: + if isinstance(stmt, AssignFunctionCall): + result.add(stmt.function_id) if not no_expressions: - insn.map_expressions(mapper) + stmt.map_expressions(mapper) return result @@ -224,9 +224,9 @@ def collect_time_ids_from_dag(dag): result = set() for phase in six.itervalues(dag.phases): - for insn in phase.instructions: - if isinstance(insn, YieldState): - result.add(insn.time_id) + for stmt in phase.statements: + if isinstance(stmt, YieldState): + result.add(stmt.time_id) return result @@ -239,9 +239,9 @@ def collect_ode_component_names_from_dag(dag): result = set() for phase in six.itervalues(dag.phases): - for insn in phase.instructions: - if isinstance(insn, YieldState): - result.add(insn.component_id) + for stmt in phase.statements: + if isinstance(stmt, YieldState): + result.add(stmt.component_id) return result diff --git a/dagrt/codegen/codegen_base.py b/dagrt/codegen/codegen_base.py index 7bab08e..1ded7c7 100644 --- a/dagrt/codegen/codegen_base.py +++ b/dagrt/codegen/codegen_base.py @@ -22,7 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -from dagrt.codegen.dag_ast import Block, IfThen, IfThenElse, InstructionWrapper +from dagrt.codegen.dag_ast import Block, IfThen, IfThenElse, StatementWrapper class StructuredCodeGenerator(object): @@ -40,8 +40,8 @@ class StructuredCodeGenerator(object): """ :arg node: An AST node to lower """ - if isinstance(node, InstructionWrapper): - self.lower_inst(node.instruction) + if isinstance(node, StatementWrapper): + self.lower_inst(node.statement) elif isinstance(node, IfThen): self.emit_if_begin(node.condition) @@ -64,14 +64,14 @@ class StructuredCodeGenerator(object): type=type(node).__name__)) def lower_inst(self, inst): - """Emit the code for an instruction.""" + """Emit the code for an statement.""" method_name = "emit_inst_"+type(inst).__name__ try: method = getattr(self, method_name) except AttributeError: raise RuntimeError( - "{gen} cannot handle instruction of type {inst}" + "{gen} cannot handle statement of type {inst}" .format( gen=repr(type(self)), inst=type(inst).__name__)) diff --git a/dagrt/codegen/dag_ast.py b/dagrt/codegen/dag_ast.py index bd855b9..4c9b5b8 100644 --- a/dagrt/codegen/dag_ast.py +++ b/dagrt/codegen/dag_ast.py @@ -91,29 +91,29 @@ class NullASTNode(Expression): mapper_method = "map_NullASTNode" -class InstructionWrapper(Expression): +class StatementWrapper(Expression): """ - .. attribute: instruction + .. attribute: statement """ - init_arg_names = ("instruction",) + init_arg_names = ("statement",) - def __init__(self, instruction): - self.instruction = instruction + def __init__(self, statement): + self.statement = statement def __getinitargs__(self): - return self.instruction, + return self.statement, - mapper_method = "map_InstructionWrapper" + mapper_method = "map_StatementWrapper" -def get_instructions_in_ast(ast): +def get_statements_in_ast(ast): """ - Return a generator that yields the instructions in the AST in linear order. + Return a generator that yields the statements in the AST in linear order. """ - if isinstance(ast, InstructionWrapper): - yield ast.instruction + if isinstance(ast, StatementWrapper): + yield ast.statement return if isinstance(ast, IfThen): @@ -126,21 +126,21 @@ def get_instructions_in_ast(ast): raise ValueError("Unknown node type: {}".format(ast.__class__.__name__)) for child in children: - for inst in get_instructions_in_ast(child): + for inst in get_statements_in_ast(child): yield inst def create_ast_from_phase(code, phase_name): """ - Return an AST representation of the instructions corresponding to the phase + Return an AST representation of the statements corresponding to the phase named `phase` as found in the :class:`DAGCode` instance `code`. """ phase = code.phases[phase_name] - # Construct a topological order of the instructions. + # Construct a topological order of the statements. stack = [] - instruction_map = dict((inst.id, inst) for inst in phase.instructions) + statement_map = dict((inst.id, inst) for inst in phase.statements) visiting = set() visited = set() topological_order = [] @@ -149,48 +149,48 @@ def create_ast_from_phase(code, phase_name): stack.extend(sorted(phase.depends_on)) while stack: - instruction = stack[-1] - if instruction in visited: - if instruction in visiting: - visiting.remove(instruction) - topological_order.append(instruction) + statement = stack[-1] + if statement in visited: + if statement in visiting: + visiting.remove(statement) + topological_order.append(statement) stack.pop() else: - visited.add(instruction) - visiting.add(instruction) + visited.add(statement) + visiting.add(statement) stack.extend( - sorted(instruction_map[instruction].depends_on)) + sorted(statement_map[statement].depends_on)) # Convert the topological order to an AST. main_block = [] from pymbolic.primitives import LogicalAnd - for instruction in map(instruction_map.__getitem__, topological_order): - if isinstance(instruction, Nop): + for statement in map(statement_map.__getitem__, topological_order): + if isinstance(statement, Nop): continue - # Instructions become AST nodes. An unconditional instruction is wrapped - # into an InstructionWrapper, while conditional instructions are wrapped + # Statements become AST nodes. An unconditional statement is wrapped + # into an StatementWrapper, while conditional statements are wrapped # using IfThens. - if isinstance(instruction.condition, LogicalAnd): + if isinstance(statement.condition, LogicalAnd): # LogicalAnd(c1, c2, ...) => IfThen(c1, IfThen(c2, ...)) - conditions = reversed(instruction.condition.children) + conditions = reversed(statement.condition.children) inst = IfThenElse(next(conditions), - InstructionWrapper(instruction.copy(condition=True)), + StatementWrapper(statement.copy(condition=True)), NullASTNode()) for next_cond in conditions: inst = IfThenElse(next_cond, inst, NullASTNode()) main_block.append(inst) - elif instruction.condition is not True: - main_block.append(IfThenElse(instruction.condition, - InstructionWrapper(instruction.copy(condition=True)), + elif statement.condition is not True: + main_block.append(IfThenElse(statement.condition, + StatementWrapper(statement.copy(condition=True)), NullASTNode())) else: - main_block.append(InstructionWrapper(instruction)) + main_block.append(StatementWrapper(statement)) ast = Block(*main_block) @@ -228,8 +228,8 @@ class ASTIdentityMapper(IdentityMapper): def map_NullASTNode(self, expr): return type(expr)() - def map_InstructionWrapper(self, expr): - return type(expr)(expr.instruction) + def map_StatementWrapper(self, expr): + return type(expr)(expr.statement) class ASTPreSimplifyMapper(ASTIdentityMapper): @@ -274,8 +274,8 @@ class ASTPostSimplifyMapper(ASTIdentityMapper): else: return Block(*new_children) - def map_InstructionWrapper(self, expr): - return InstructionWrapper(expr.instruction) + def map_StatementWrapper(self, expr): + return StatementWrapper(expr.statement) class ASTSimplifyMapper(ASTIdentityMapper): diff --git a/dagrt/codegen/data.py b/dagrt/codegen/data.py index 61176fb..11b6a9a 100644 --- a/dagrt/codegen/data.py +++ b/dagrt/codegen/data.py @@ -35,11 +35,11 @@ from pytools import RecordWithoutPickling from pymbolic.mapper import Mapper -def _get_arg_dict_from_call_insn(insn): +def _get_arg_dict_from_call_stmt(stmt): arg_dict = {} - for i, arg_val in enumerate(insn.parameters): + for i, arg_val in enumerate(stmt.parameters): arg_dict[i] = arg_val - for arg_name, arg_val in insn.kw_parameters.items(): + for arg_name, arg_val in stmt.kw_parameters.items(): arg_dict[arg_name] = arg_val return arg_dict @@ -410,7 +410,7 @@ class SymbolKindFinder(object): result = SymbolKindTable() - from dagrt.codegen.dag_ast import get_instructions_in_ast + from dagrt.codegen.dag_ast import get_statements_in_ast def make_kim(func_name, check): return KindInferenceMapper( @@ -420,38 +420,38 @@ class SymbolKindFinder(object): check=False) while True: - insn_queue = [] + stmt_queue = [] for name, func in zip(names, functions): - insn_queue.extend( - (name, insn) - for insn in get_instructions_in_ast(func)) + stmt_queue.extend( + (name, stmt) + for stmt in get_statements_in_ast(func)) - insn_queue_push_buffer = [] + stmt_queue_push_buffer = [] made_progress = False result.reset_change_flag() - while insn_queue or insn_queue_push_buffer: - if not insn_queue: + while stmt_queue or stmt_queue_push_buffer: + if not stmt_queue: # {{{ provide a usable error message if no progress if not made_progress: - print("Left-over instructions in kind inference:") - for func_name, insn in insn_queue_push_buffer: - print("[%s] %s" % (func_name, insn)) + print("Left-over statements in kind inference:") + for func_name, stmt in stmt_queue_push_buffer: + print("[%s] %s" % (func_name, stmt)) kim = make_kim(func_name, check=False) try: - if isinstance(insn, lang.AssignExpression): - kim(insn.expression) + if isinstance(stmt, lang.AssignExpression): + kim(stmt.expression) - elif isinstance(insn, lang.AssignFunctionCall): - kim.map_generic_call(insn.function_id, - _get_arg_dict_from_call_insn(insn), + elif isinstance(stmt, lang.AssignFunctionCall): + kim.map_generic_call(stmt.function_id, + _get_arg_dict_from_call_stmt(stmt), single_return_only=False) - elif isinstance(insn, lang.AssignmentBase): + elif isinstance(stmt, lang.AssignmentBase): raise TODO() else: @@ -468,44 +468,44 @@ class SymbolKindFinder(object): # }}} - insn_queue = insn_queue_push_buffer - insn_queue_push_buffer = [] + stmt_queue = stmt_queue_push_buffer + stmt_queue_push_buffer = [] made_progress = False - func_name, insn = insn_queue.pop() + func_name, stmt = stmt_queue.pop() - if isinstance(insn, lang.AssignExpression): + if isinstance(stmt, lang.AssignExpression): kim = make_kim(func_name, check=False) - for ident, _, _ in insn.loops: + for ident, _, _ in stmt.loops: result.set(func_name, ident, kind=Integer()) - if insn.assignee_subscript: + if stmt.assignee_subscript: continue try: - kind = kim(insn.expression) + kind = kim(stmt.expression) except UnableToInferKind: - insn_queue_push_buffer.append((func_name, insn)) + stmt_queue_push_buffer.append((func_name, stmt)) else: made_progress = True - result.set(func_name, insn.assignee, kind=kind) + result.set(func_name, stmt.assignee, kind=kind) - elif isinstance(insn, lang.AssignFunctionCall): + elif isinstance(stmt, lang.AssignFunctionCall): kim = make_kim(func_name, check=False) try: - kinds = kim.map_generic_call(insn.function_id, - _get_arg_dict_from_call_insn(insn), + kinds = kim.map_generic_call(stmt.function_id, + _get_arg_dict_from_call_stmt(stmt), single_return_only=False) except UnableToInferKind: - insn_queue_push_buffer.append((func_name, insn)) + stmt_queue_push_buffer.append((func_name, stmt)) else: made_progress = True - for assignee, kind in zip(insn.assignees, kinds): + for assignee, kind in zip(stmt.assignees, kinds): result.set(func_name, assignee, kind=kind) - elif isinstance(insn, lang.AssignmentBase): + elif isinstance(stmt, lang.AssignmentBase): raise TODO() else: @@ -520,25 +520,25 @@ class SymbolKindFinder(object): for func_name, func in zip(names, functions): kim = make_kim(func_name, check=True) - for insn in get_instructions_in_ast(func): - if isinstance(insn, lang.AssignExpression): - kim(insn.expression) + for stmt in get_statements_in_ast(func): + if isinstance(stmt, lang.AssignExpression): + kim(stmt.expression) - elif isinstance(insn, lang.AssignFunctionCall): - kim.map_generic_call(insn.function_id, - _get_arg_dict_from_call_insn(insn), + elif isinstance(stmt, lang.AssignFunctionCall): + kim.map_generic_call(stmt.function_id, + _get_arg_dict_from_call_stmt(stmt), single_return_only=False) - func = self.function_registry[insn.function_id] - if len(func.result_names) != len(insn.assignees): + func = self.function_registry[stmt.function_id] + if len(func.result_names) != len(stmt.assignees): raise ValueError("number of function return values " "for '%s' (%d) " "and number of assigned variables (%d) " "do not match" - % (insn.function_id, - len(func.result_names), len(insn.assignees))) + % (stmt.function_id, + len(func.result_names), len(stmt.assignees))) - elif isinstance(insn, lang.AssignmentBase): + elif isinstance(stmt, lang.AssignmentBase): raise TODO() else: diff --git a/dagrt/codegen/fortran.py b/dagrt/codegen/fortran.py index e4c8a5d..8f55710 100644 --- a/dagrt/codegen/fortran.py +++ b/dagrt/codegen/fortran.py @@ -2081,7 +2081,7 @@ class CodeGenerator(StructuredCodeGenerator): assignee_fortran_name, assignee_subscript, expr, sym_kind) def lower_inst(self, inst): - """Emit the code for an instruction.""" + """Emit the code for an statement.""" self.emit("! {{{ %s" % inst) self.emit("") diff --git a/dagrt/codegen/python.py b/dagrt/codegen/python.py index cf09a68..0d1cd1e 100644 --- a/dagrt/codegen/python.py +++ b/dagrt/codegen/python.py @@ -217,8 +217,8 @@ class CodeGenerator(StructuredCodeGenerator): def _pre_lower(self, ast): self._has_yield_inst = False from dagrt.language import YieldState - from dagrt.codegen.dag_ast import get_instructions_in_ast - for inst in get_instructions_in_ast(ast): + from dagrt.codegen.dag_ast import get_statements_in_ast + for inst in get_statements_in_ast(ast): if isinstance(inst, YieldState): self._has_yield_inst = True return @@ -404,7 +404,7 @@ class CodeGenerator(StructuredCodeGenerator): if not self._has_yield_inst: self._emit('yield') - # {{{ instructions + # {{{ statements def emit_inst_AssignExpression(self, inst): emitter = self._emitter diff --git a/dagrt/codegen/transform.py b/dagrt/codegen/transform.py index b05ce55..578a8cf 100644 --- a/dagrt/codegen/transform.py +++ b/dagrt/codegen/transform.py @@ -31,22 +31,22 @@ from pymbolic.mapper import IdentityMapper # {{{ eliminate self dependencies def eliminate_self_dependencies(dag): - insn_id_gen = dag.get_insn_id_generator() + stmt_id_gen = dag.get_stmt_id_generator() var_name_gen = dag.get_var_name_generator() new_phases = {} for phase_name, phase in six.iteritems(dag.phases): - new_instructions = [] - for insn in sorted(phase.instructions, key=lambda insn: insn.id): + new_statements = [] + for stmt in sorted(phase.statements, key=lambda stmt: stmt.id): read_and_written = ( - insn.get_read_variables() & insn.get_written_variables()) + stmt.get_read_variables() & stmt.get_written_variables()) if not read_and_written: - new_instructions.append(insn) + new_statements.append(stmt) continue substs = [] - tmp_insn_ids = [] + tmp_stmt_ids = [] from dagrt.language import AssignExpression from pymbolic import var @@ -56,28 +56,28 @@ def eliminate_self_dependencies(dag): + var_name.replace("<", "_").replace(">", "_")) substs.append((var_name, var(tmp_var_name))) - tmp_insn_id = insn_id_gen("temp") - tmp_insn_ids.append(tmp_insn_id) + tmp_stmt_id = stmt_id_gen("temp") + tmp_stmt_ids.append(tmp_stmt_id) - new_tmp_insn = AssignExpression( + new_tmp_stmt = AssignExpression( tmp_var_name, (), var(var_name), - condition=insn.condition, - id=tmp_insn_id, - depends_on=insn.depends_on) - new_instructions.append(new_tmp_insn) + condition=stmt.condition, + id=tmp_stmt_id, + depends_on=stmt.depends_on) + new_statements.append(new_tmp_stmt) from pymbolic import substitute - new_insn = (insn + new_stmt = (stmt .map_expressions( lambda expr: substitute(expr, dict(substs)), include_lhs=False) .copy( # lhs will be rewritten, but we don't want that. - depends_on=insn.depends_on | frozenset(tmp_insn_ids))) + depends_on=stmt.depends_on | frozenset(tmp_stmt_ids))) - new_instructions.append(new_insn) + new_statements.append(new_stmt) - new_phases[phase_name] = phase.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(statements=new_statements) return dag.copy(phases=new_phases) @@ -87,11 +87,11 @@ def eliminate_self_dependencies(dag): # {{{ isolate function arguments class FunctionArgumentIsolator(IdentityMapper): - def __init__(self, new_instructions, - insn_id_gen, var_name_gen): + def __init__(self, new_statements, + stmt_id_gen, var_name_gen): super(IdentityMapper, self).__init__() - self.new_instructions = new_instructions - self.insn_id_gen = insn_id_gen + self.new_statements = new_statements + self.stmt_id_gen = stmt_id_gen self.var_name_gen = var_name_gen def isolate_arg(self, expr, base_condition, base_deps, extra_deps): @@ -102,21 +102,21 @@ class FunctionArgumentIsolator(IdentityMapper): # FIXME: These aren't awesome identifiers. tmp_var_name = self.var_name_gen("tmp") - tmp_insn_id = self.insn_id_gen("tmp") - extra_deps.append(tmp_insn_id) + tmp_stmt_id = self.stmt_id_gen("tmp") + extra_deps.append(tmp_stmt_id) sub_extra_deps = [] rec_result = self.rec( expr, base_condition, base_deps, sub_extra_deps) from dagrt.language import AssignExpression - new_insn = AssignExpression( + new_stmt = AssignExpression( tmp_var_name, (), rec_result, condition=base_condition, depends_on=base_deps | frozenset(sub_extra_deps), - id=tmp_insn_id) + id=tmp_stmt_id) - self.new_instructions.append(new_insn) + self.new_statements.append(new_stmt) from pymbolic import var return var(tmp_var_name) @@ -140,30 +140,30 @@ class FunctionArgumentIsolator(IdentityMapper): def isolate_function_arguments(dag): - insn_id_gen = dag.get_insn_id_generator() + stmt_id_gen = dag.get_stmt_id_generator() var_name_gen = dag.get_var_name_generator() new_phases = {} for phase_name, phase in six.iteritems(dag.phases): - new_instructions = [] + new_statements = [] fai = FunctionArgumentIsolator( - new_instructions=new_instructions, - insn_id_gen=insn_id_gen, + new_statements=new_statements, + stmt_id_gen=stmt_id_gen, var_name_gen=var_name_gen) - for insn in sorted(phase.instructions, key=lambda insn: insn.id): - base_deps = insn.depends_on + for stmt in sorted(phase.statements, key=lambda stmt: stmt.id): + base_deps = stmt.depends_on new_deps = [] - new_instructions.append( - insn + new_statements.append( + stmt .map_expressions( lambda expr: fai( - expr, insn.condition, base_deps, new_deps)) - .copy(depends_on=insn.depends_on | frozenset(new_deps))) + expr, stmt.condition, base_deps, new_deps)) + .copy(depends_on=stmt.depends_on | frozenset(new_deps))) - new_phases[phase_name] = phase.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(statements=new_statements) return dag.copy(phases=new_phases) @@ -173,11 +173,11 @@ def isolate_function_arguments(dag): # {{{ isolate function calls class FunctionCallIsolator(IdentityMapper): - def __init__(self, new_instructions, - insn_id_gen, var_name_gen): + def __init__(self, new_statements, + stmt_id_gen, var_name_gen): super(IdentityMapper, self).__init__() - self.new_instructions = new_instructions - self.insn_id_gen = insn_id_gen + self.new_statements = new_statements + self.stmt_id_gen = stmt_id_gen self.var_name_gen = var_name_gen def isolate_call(self, expr, base_condition, base_deps, extra_deps, @@ -185,8 +185,8 @@ class FunctionCallIsolator(IdentityMapper): # FIXME: These aren't awesome identifiers. tmp_var_name = self.var_name_gen("tmp") - tmp_insn_id = self.insn_id_gen("tmp") - extra_deps.append(tmp_insn_id) + tmp_stmt_id = self.stmt_id_gen("tmp") + extra_deps.append(tmp_stmt_id) sub_extra_deps = [] rec_result = super_method( @@ -206,16 +206,16 @@ class FunctionCallIsolator(IdentityMapper): kw_parameters[par_name] = par from dagrt.language import AssignFunctionCall - new_insn = AssignFunctionCall( + new_stmt = AssignFunctionCall( assignees=(tmp_var_name,), function_id=rec_result.function.name, parameters=tuple(parameters), kw_parameters=kw_parameters, - id=tmp_insn_id, + id=tmp_stmt_id, condition=base_condition, depends_on=base_deps | frozenset(sub_extra_deps)) - self.new_instructions.append(new_insn) + self.new_statements.append(new_stmt) from pymbolic import var return var(tmp_var_name) @@ -238,36 +238,36 @@ def isolate_function_calls(dag): called before this. """ - insn_id_gen = dag.get_insn_id_generator() + stmt_id_gen = dag.get_stmt_id_generator() var_name_gen = dag.get_var_name_generator() new_phases = {} for phase_name, phase in six.iteritems(dag.phases): - new_instructions = [] + new_statements = [] fci = FunctionCallIsolator( - new_instructions=new_instructions, - insn_id_gen=insn_id_gen, + new_statements=new_statements, + stmt_id_gen=stmt_id_gen, var_name_gen=var_name_gen) - for insn in sorted(phase.instructions, key=lambda insn: insn.id): + for stmt in sorted(phase.statements, key=lambda stmt: stmt.id): new_deps = [] from dagrt.language import AssignExpression - if isinstance(insn, AssignExpression): - new_instructions.append( - insn + if isinstance(stmt, AssignExpression): + new_statements.append( + stmt .map_expressions( lambda expr: fci( - expr, insn.condition, insn.depends_on, new_deps)) - .copy(depends_on=insn.depends_on | frozenset(new_deps))) + expr, stmt.condition, stmt.depends_on, new_deps)) + .copy(depends_on=stmt.depends_on | frozenset(new_deps))) from pymbolic.primitives import Call, CallWithKwargs - assert not isinstance(new_instructions[-1].rhs, + assert not isinstance(new_statements[-1].rhs, (Call, CallWithKwargs)) else: - new_instructions.append(insn) + new_statements.append(stmt) - new_phases[phase_name] = phase.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(statements=new_statements) return dag.copy(phases=new_phases) @@ -289,10 +289,10 @@ def flat_LogicalAnd(*children): # noqa class IfThenElseExpander(IdentityMapper): - def __init__(self, new_instructions, insn_id_gen, var_name_gen): + def __init__(self, new_statements, stmt_id_gen, var_name_gen): super(IfThenElseExpander, self).__init__() - self.new_instructions = new_instructions - self.insn_id_gen = insn_id_gen + self.new_statements = new_statements + self.stmt_id_gen = stmt_id_gen self.var_name_gen = var_name_gen def map_if(self, expr, base_condition, base_deps, extra_deps): @@ -301,9 +301,9 @@ class IfThenElseExpander(IdentityMapper): flag = var(self.var_name_gen("ifthenelse_cond")) tmp_result = self.var_name_gen("ifthenelse_result") - if_insn_id = self.insn_id_gen("ifthenelse_cond") - then_insn_id = self.insn_id_gen("ifthenelse_then") - else_insn_id = self.insn_id_gen("ifthenelse_else") + if_stmt_id = self.stmt_id_gen("ifthenelse_cond") + then_stmt_id = self.stmt_id_gen("ifthenelse_then") + else_stmt_id = self.stmt_id_gen("ifthenelse_else") sub_condition_deps = [] rec_condition = self.rec(expr.condition, base_condition, base_deps, @@ -312,74 +312,74 @@ class IfThenElseExpander(IdentityMapper): sub_then_deps = [] then_condition = flat_LogicalAnd(base_condition, flag) rec_then = self.rec(expr.then, then_condition, - base_deps | frozenset([if_insn_id]), sub_then_deps) + base_deps | frozenset([if_stmt_id]), sub_then_deps) sub_else_deps = [] else_condition = flat_LogicalAnd(base_condition, LogicalNot(flag)) rec_else = self.rec(expr.else_, else_condition, - base_deps | frozenset([if_insn_id]), sub_else_deps) + base_deps | frozenset([if_stmt_id]), sub_else_deps) from dagrt.language import AssignExpression - self.new_instructions.extend([ + self.new_statements.extend([ AssignExpression( assignee=flag.name, assignee_subscript=(), expression=rec_condition, condition=base_condition, - id=if_insn_id, + id=if_stmt_id, depends_on=base_deps | frozenset(sub_condition_deps)), AssignExpression( assignee=tmp_result, assignee_subscript=(), condition=then_condition, expression=rec_then, - id=then_insn_id, + id=then_stmt_id, depends_on=( base_deps | frozenset(sub_then_deps) | - frozenset([if_insn_id]))), + frozenset([if_stmt_id]))), AssignExpression( assignee=tmp_result, assignee_subscript=(), condition=else_condition, expression=rec_else, - id=else_insn_id, + id=else_stmt_id, depends_on=base_deps | frozenset(sub_else_deps) | - frozenset([if_insn_id]))]) + frozenset([if_stmt_id]))]) - extra_deps.extend([then_insn_id, else_insn_id]) + extra_deps.extend([then_stmt_id, else_stmt_id]) return var(tmp_result) def expand_IfThenElse(dag): # noqa """ Turn IfThenElse expressions into values that are computed as a result of an - If instruction. This is useful for targets that do not support ternary + If statement. This is useful for targets that do not support ternary operators. """ - insn_id_gen = dag.get_insn_id_generator() + stmt_id_gen = dag.get_stmt_id_generator() var_name_gen = dag.get_var_name_generator() new_phases = {} for phase_name, phase in six.iteritems(dag.phases): - new_instructions = [] + new_statements = [] expander = IfThenElseExpander( - new_instructions=new_instructions, - insn_id_gen=insn_id_gen, + new_statements=new_statements, + stmt_id_gen=stmt_id_gen, var_name_gen=var_name_gen) - for insn in phase.instructions: - base_deps = insn.depends_on + for stmt in phase.statements: + base_deps = stmt.depends_on new_deps = [] - new_instructions.append( - insn.map_expressions( - lambda expr: expander(expr, insn.condition, base_deps, new_deps)) - .copy(depends_on=insn.depends_on | frozenset(new_deps))) + new_statements.append( + stmt.map_expressions( + lambda expr: expander(expr, stmt.condition, base_deps, new_deps)) + .copy(depends_on=stmt.depends_on | frozenset(new_deps))) - new_phases[phase_name] = phase.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(statements=new_statements) return dag.copy(phases=new_phases) diff --git a/dagrt/exec_numpy.py b/dagrt/exec_numpy.py index c3a53d6..8c3a5d9 100644 --- a/dagrt/exec_numpy.py +++ b/dagrt/exec_numpy.py @@ -190,29 +190,29 @@ class NumpyInterpreter(object): self.functions[name] = f - def evaluate_condition(self, insn): - return self.eval_mapper(insn.condition) + def evaluate_condition(self, stmt): + return self.eval_mapper(stmt.condition) # {{{ execution methods - def exec_AssignSolved(self, insn): + def exec_AssignSolved(self, stmt): raise NotImplementedError("Encountered AssignSolved.") - def exec_YieldState(self, insn): + def exec_YieldState(self, stmt): return StateComputed( - t=self.eval_mapper(insn.time), - time_id=insn.time_id, - component_id=insn.component_id, - state_component=self.eval_mapper(insn.expression)), [] - - def exec_AssignExpression(self, insn): - if not insn.loops: - if insn.assignee_subscript: - self.context[insn.assignee][ - self.eval_mapper(insn.assignee_subscript)] = \ - self.eval_mapper(insn.expression) + t=self.eval_mapper(stmt.time), + time_id=stmt.time_id, + component_id=stmt.component_id, + state_component=self.eval_mapper(stmt.expression)), [] + + def exec_AssignExpression(self, stmt): + if not stmt.loops: + if stmt.assignee_subscript: + self.context[stmt.assignee][ + self.eval_mapper(stmt.assignee_subscript)] = \ + self.eval_mapper(stmt.expression) else: - self.context[insn.assignee] = self.eval_mapper(insn.expression) + self.context[stmt.assignee] = self.eval_mapper(stmt.expression) else: def implement_loops(loops): @@ -228,54 +228,54 @@ class NumpyInterpreter(object): for val in implement_loops(loops[1:]): yield - for val in implement_loops(insn.loops): - if insn.assignee_subscript: - self.context[insn.assignee][ - self.eval_mapper(insn.assignee_subscript)] = \ - self.eval_mapper(insn.expression) + for val in implement_loops(stmt.loops): + if stmt.assignee_subscript: + self.context[stmt.assignee][ + self.eval_mapper(stmt.assignee_subscript)] = \ + self.eval_mapper(stmt.expression) else: - self.context[insn.assignee] = self.eval_mapper(insn.expression) + self.context[stmt.assignee] = self.eval_mapper(stmt.expression) - for ident, _, _ in insn.loops: + for ident, _, _ in stmt.loops: del self.context[ident] - def exec_AssignFunctionCall(self, insn): + def exec_AssignFunctionCall(self, stmt): parameters = [ self.eval_mapper(expr) - for expr in insn.parameters] + for expr in stmt.parameters] kw_parameters = dict( (name, self.eval_mapper(expr)) - for name, expr in insn.kw_parameters.items()) + for name, expr in stmt.kw_parameters.items()) - func = self.eval_mapper.functions[insn.function_id] + func = self.eval_mapper.functions[stmt.function_id] results = func(*parameters, **kw_parameters) - if len(insn.assignees) == 0: + if len(stmt.assignees) == 0: return - if len(insn.assignees) == 1: + if len(stmt.assignees) == 1: results = (results,) - assert len(results) == len(insn.assignees) + assert len(results) == len(stmt.assignees) - for assignee, res in zip(insn.assignees, results): + for assignee, res in zip(stmt.assignees, results): self.context[assignee] = res - def exec_Raise(self, insn): - raise insn.error_condition(insn.error_message) + def exec_Raise(self, stmt): + raise stmt.error_condition(stmt.error_message) - def exec_FailStep(self, insn): + def exec_FailStep(self, stmt): raise FailStepException() - def exec_ExitStep(self, insn): + def exec_ExitStep(self, stmt): raise ExitStepException() - def exec_Nop(self, insn): + def exec_Nop(self, stmt): pass - def exec_PhaseTransition(self, insn): - raise TransitionEvent(insn.next_phase) + def exec_PhaseTransition(self, stmt): + raise TransitionEvent(stmt.next_phase) # }}} diff --git a/dagrt/language.py b/dagrt/language.py index 891e706..150f64b 100644 --- a/dagrt/language.py +++ b/dagrt/language.py @@ -26,8 +26,8 @@ THE SOFTWARE. """ from pytools import RecordWithoutPickling, memoize_method -from pymbolic.imperative.instruction import ( - ConditionalInstruction as InstructionBase, +from pymbolic.imperative.statement import ( + ConditionalStatement as StatementBase, ConditionalAssignment as AssignExpressionBase, Nop as NopBase) @@ -40,7 +40,7 @@ import six.moves logger = logging.getLogger(__name__) -# {{{ instructions +# {{{ statements __doc__ = """ Identifier conventions @@ -99,23 +99,23 @@ See :mod:`dagrt.function_registry` for interpretation of function names. The function namespace and the variable namespace are distinct. No user-defined identifiers should start with `dagrt_`. -Instructions +Statements ~~~~~~~~~~~~ -.. autoclass:: Instruction +.. autoclass:: Statement -Assignment Instructions +Assignment Statements ^^^^^^^^^^^^^^^^^^^^^^^ -These instructions perform updates to the execution state, i.e. the variables. +These statements perform updates to the execution state, i.e. the variables. .. autoclass:: AssignSolved .. autoclass:: AssignExpression .. autoclass:: AssignFunctionCall -Control Instructions +Control Statements ^^^^^^^^^^^^^^^^^^^^ -These instructions affect the execution of a phase, or cause a phase to interact +These statements affect the execution of a phase, or cause a phase to interact with user code. .. autoclass:: YieldState @@ -124,7 +124,7 @@ with user code. .. autoclass:: ExitStep .. autoclass:: PhaseTransition -Miscellaneous Instructions +Miscellaneous Statements ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. autoclass:: Nop @@ -153,32 +153,32 @@ Code Creation # {{{ utilities -def _stringify_instructions(roots, id_to_insn, prefix=""): +def _stringify_statements(roots, id_to_stmt, prefix=""): lines = [] - printed_insn_ids = set() + printed_stmt_ids = set() - def print_insn(insn): - if insn.id in printed_insn_ids: + def print_stmt(stmt): + if stmt.id in printed_stmt_ids: return - printed_insn_ids.add(insn.id) + printed_stmt_ids.add(stmt.id) - for dep_id in insn.depends_on: - print_insn(id_to_insn[dep_id]) + for dep_id in stmt.depends_on: + print_stmt(id_to_stmt[dep_id]) lines.append( "%s{%s} %s" % ( - prefix, insn.id, str(insn).replace("\n", "\n "))) + prefix, stmt.id, str(stmt).replace("\n", "\n "))) - for root_insn in roots: - print_insn(root_insn) + for root_stmt in roots: + print_stmt(root_stmt) return lines # }}} -class Instruction(InstructionBase): +class Statement(StatementBase): def get_dependency_mapper(self, include_calls="descend_args"): from dagrt.expression import ExtendedDependencyMapper return ExtendedDependencyMapper( @@ -193,11 +193,11 @@ class Nop(NopBase): # {{{ assignments -class AssignmentBase(Instruction): +class AssignmentBase(Statement): pass -class AssignExpression(Instruction, AssignExpressionBase): +class AssignExpression(Statement, AssignExpressionBase): """ .. attribute:: loops @@ -323,7 +323,7 @@ class AssignSolved(AssignmentBase): def __init__(self, assignees, solve_variables, expressions, other_params, solver_id, **kwargs): - Instruction.__init__(self, assignees=assignees, + Statement.__init__(self, assignees=assignees, solve_variables=solve_variables, expressions=expressions, other_params=other_params, @@ -386,13 +386,13 @@ class AssignSolved(AssignmentBase): class AssignFunctionCall(AssignmentBase): - """This instruction encodes function calls. It should be noted + """This statement encodes function calls. It should be noted that function calls can *also* be encoded as expressions - involving calls, however the existence of this separate instruction + involving calls, however the existence of this separate statement is justified by two facts: * Some backends (such as Fortran) choose to separate out function calls - into individual instructions. This instruction provides a + into individual statements. This statement provides a natural way to encode them. See :class:`leam.vm.codegen.transform.FunctionCallIsolator` for @@ -486,7 +486,7 @@ class AssignFunctionCall(AssignmentBase): # }}} -class YieldState(Instruction): +class YieldState(Statement): """ .. attribute:: time_id .. attribute:: time @@ -525,7 +525,7 @@ class YieldState(Instruction): exec_method = six.moves.intern("exec_YieldState") -class Raise(Instruction): +class Raise(Statement): """ .. attribute:: error_condition @@ -537,7 +537,7 @@ class Raise(Instruction): """ def __init__(self, error_condition, error_message=None, **kwargs): - Instruction.__init__(self, + Statement.__init__(self, error_condition=error_condition, error_message=error_message, **kwargs) @@ -556,7 +556,7 @@ class Raise(Instruction): exec_method = six.moves.intern("exec_Raise") -class PhaseTransition(Instruction): +class PhaseTransition(Statement): """ .. attribute:: next_phase @@ -564,7 +564,7 @@ class PhaseTransition(Instruction): """ def __init__(self, next_phase, **kwargs): - Instruction.__init__(self, next_phase=next_phase, **kwargs) + Statement.__init__(self, next_phase=next_phase, **kwargs) def get_written_variables(self): return frozenset() @@ -576,7 +576,7 @@ class PhaseTransition(Instruction): exec_method = six.moves.intern("exec_PhaseTransition") -class FailStep(Instruction): +class FailStep(Statement): """Exits the current step with a failure indication to the controlling program. Execution resumes with the next step as normal. """ @@ -590,7 +590,7 @@ class FailStep(Instruction): exec_method = six.moves.intern("exec_FailStep") -class ExitStep(Instruction): +class ExitStep(Statement): """Exits the current step. Execution resumes with the next step as normal. """ @@ -611,7 +611,7 @@ class ExecutionPhase(RecordWithoutPickling): """ .. attribute:: depends_on - a list of instruction IDs that need to be accomplished + a list of statement IDs that need to be accomplished for successful execution of one round of this state .. attribute:: next_phase @@ -619,25 +619,25 @@ class ExecutionPhase(RecordWithoutPickling): name of the next state after this one, if no other state is specified by the user. - .. attribute:: instructions + .. attribute:: statements - is a list of Instruction instances, in no particular - order. Only instructions referred to by :attr:`depends_on` + is a list of Statement instances, in no particular + order. Only statements referred to by :attr:`depends_on` or the transitive closure of their dependency relations will actually be executed. """ - def __init__(self, depends_on, next_phase, instructions): + def __init__(self, depends_on, next_phase, statements): super(ExecutionPhase, self).__init__( depends_on=depends_on, next_phase=next_phase, - instructions=instructions) + statements=statements) @property @memoize_method - def id_to_insn(self): - return dict((insn.id, insn) - for insn in self.instructions) + def id_to_stmt(self): + return dict((stmt.id, stmt) + for stmt in self.statements) class DAGCode(RecordWithoutPickling): @@ -653,24 +653,24 @@ class DAGCode(RecordWithoutPickling): """ @classmethod - def create_with_steady_phase(cls, dep_on, instructions): + def create_with_steady_phase(cls, dep_on, statements): phases = {'main': ExecutionPhase( - dep_on, next_phase='main', instructions=instructions)} + dep_on, next_phase='main', statements=statements)} return cls(phases, 'main') @classmethod def _create_with_init_and_step(cls, initialization_dep_on, - step_dep_on, instructions): + step_dep_on, statements): phases = {} phases['initialization'] = ExecutionPhase( initialization_dep_on, next_phase='primary', - instructions=instructions) + statements=statements) phases['primary'] = ExecutionPhase( step_dep_on, next_phase='primary', - instructions=instructions) + statements=statements) return cls(phases, 'initialization') @@ -682,19 +682,19 @@ class DAGCode(RecordWithoutPickling): # {{{ identifier wrangling - def get_insn_id_generator(self): + def get_stmt_id_generator(self): from pytools import UniqueNameGenerator return UniqueNameGenerator( - set(insn.id + set(stmt.id for phase in six.itervalues(self.phases) - for insn in phase.instructions)) + for stmt in phase.statements)) def existing_var_names(self): result = set() for state in six.itervalues(self.phases): - for insn in state.instructions: - result.update(insn.get_written_variables()) - result.update(insn.get_read_variables()) + for stmt in state.statements: + result.update(stmt.get_written_variables()) + result.update(stmt.get_read_variables()) return result @@ -710,9 +710,9 @@ class DAGCode(RecordWithoutPickling): lines.append("STAGE %s" % phase_name) for root_id in phase.depends_on: - lines.extend(_stringify_instructions( - [phase.id_to_insn[root_id]], - phase.id_to_insn, prefix=" ")) + lines.extend(_stringify_statements( + [phase.id_to_stmt[root_id]], + phase.id_to_stmt, prefix=" ")) lines.append(" -> (next phase) %s" % phase.next_phase) lines.append("") @@ -741,59 +741,59 @@ class ExecutionController(object): self.executed_ids.clear() def update_plan(self, phase, execute_ids): - """Update the plan with the minimal list of instruction ids to execute - so that the instruction IDs in execute_ids will be executed before any + """Update the plan with the minimal list of statement ids to execute + so that the statement IDs in execute_ids will be executed before any others and such that all their dependencies are satisfied. """ early_plan = [] - id_to_insn = phase.id_to_insn + id_to_stmt = phase.id_to_stmt - def add_with_deps(insn): - insn_id = insn.id - if insn_id in self.executed_ids: + def add_with_deps(stmt): + stmt_id = stmt.id + if stmt_id in self.executed_ids: # Already done, no need to think more. return - if insn_id in self.plan_id_set: + if stmt_id in self.plan_id_set: # Already in plan, no need to think more. return - if insn_id in early_plan: + if stmt_id in early_plan: return - for dep_id in insn.depends_on: - add_with_deps(id_to_insn[dep_id]) + for dep_id in stmt.depends_on: + add_with_deps(id_to_stmt[dep_id]) - assert insn_id not in self.plan_id_set + assert stmt_id not in self.plan_id_set - early_plan.append(insn_id) + early_plan.append(stmt_id) - for insn_id in execute_ids: - add_with_deps(id_to_insn[insn_id]) + for stmt_id in execute_ids: + add_with_deps(id_to_stmt[stmt_id]) self.plan = early_plan + self.plan self.plan_id_set.update(early_plan) def __call__(self, phase, target): - id_to_insn = phase.id_to_insn + id_to_stmt = phase.id_to_stmt while self.plan: - insn_id = self.plan.pop(0) - self.plan_id_set.remove(insn_id) + stmt_id = self.plan.pop(0) + self.plan_id_set.remove(stmt_id) - self.executed_ids.add(insn_id) + self.executed_ids.add(stmt_id) - insn = id_to_insn[insn_id] + stmt = id_to_stmt[stmt_id] logger.debug("execution trace: [%s] %s" % ( - insn.id, str(insn).replace("\n", " | "))) + stmt.id, str(stmt).replace("\n", " | "))) - if not target.evaluate_condition(insn): + if not target.evaluate_condition(stmt): continue - result = getattr(target, insn.exec_method)(insn) + result = getattr(target, stmt.exec_method)(stmt) if result is not None: event, new_deps = result if event is not None: @@ -809,15 +809,15 @@ class ExecutionController(object): class CodeBuilder(object): """ - .. attribute:: instructions + .. attribute:: statements - The set of instructions generated for the phase + The set of statements generated for the phase .. attribute:: phase_dependencies - A list of instruction names. Starting with these instructions + A list of statement names. Starting with these statements as the root dependencies, the phase can be executed by following - the dependency list of each instruction. + the dependency list of each statement. .. automethod:: fence .. automethod:: if_ @@ -838,23 +838,23 @@ class CodeBuilder(object): class Context(RecordWithoutPickling): """ - A context represents a block of instructions being built into the DAG + A context represents a block of statements being built into the DAG - .. attribute:: lead_instruction_ids + .. attribute:: lead_statement_ids .. attribute:: introduced_condition - .. attribute:: context_instruction_ids + .. attribute:: context_statement_ids .. attribute:: used_variables .. attribute:: definition_map """ - def __init__(self, lead_instruction_ids=[], definition_map={}, + def __init__(self, lead_statement_ids=[], definition_map={}, used_variables=[], condition=True): RecordWithoutPickling.__init__(self, - lead_instruction_ids=frozenset(lead_instruction_ids), - context_instruction_ids=set(lead_instruction_ids), + lead_statement_ids=frozenset(lead_statement_ids), + context_statement_ids=set(lead_statement_ids), definition_map=dict(definition_map), used_variables=set(used_variables), condition=condition) @@ -864,8 +864,8 @@ class CodeBuilder(object): :arg label: The name of the phase to generate """ self.label = label - self._instruction_map = {} - self._instruction_count = 0 + self._statement_map = {} + self._statement_count = 0 self._contexts = [] self._last_popped_context = None self._all_var_names = set() @@ -873,8 +873,8 @@ class CodeBuilder(object): def fence(self): """ - Enter a new logical block of instructions. Force all prior - instructions to execute before subsequent ones. + Enter a new logical block of statements. Force all prior + statements to execute before subsequent ones. """ self._contexts[-1] = self._make_new_context(Nop(), additional_condition=self._contexts[-1].condition) @@ -923,7 +923,7 @@ class CodeBuilder(object): else: raise ValueError("Unrecognized condition expression") - # Create an instruction as a lead instruction to assign a logical flag. + # Create an statement as a lead statement to assign a logical flag. cond_var = self.fresh_var("") cond_assignment = AssignExpression( assignee=cond_var.name, @@ -938,7 +938,7 @@ class CodeBuilder(object): # Pop myself from the stack. last_context = self._contexts.pop() self._contexts[-1] = self._make_new_context( - Nop(depends_on=last_context.context_instruction_ids), + Nop(depends_on=last_context.context_statement_ids), additional_condition=self._contexts[-1].condition) self._last_popped_if = last_context @@ -964,12 +964,12 @@ class CodeBuilder(object): last_context = self._contexts.pop() self._contexts[-1] = self._make_new_context( - Nop(depends_on=last_context.context_instruction_ids), + Nop(depends_on=last_context.context_statement_ids), additional_condition=self._contexts[-1].condition) - def _next_instruction_id(self): - self._instruction_count += 1 - return self.label + "_" + str(self._instruction_count) + def _next_statement_id(self): + self._statement_count += 1 + return self.label + "_" + str(self._statement_count) def __call__(self, assignees, expression, loops=[]): """Generate code for an assignment. @@ -1057,9 +1057,9 @@ class CodeBuilder(object): assign = __call__ def _add_inst_to_context(self, inst): - inst_id = self._next_instruction_id() + inst_id = self._next_statement_id() context = self._contexts[-1] - dependencies = set(context.lead_instruction_ids) + dependencies = set(context.lead_statement_ids) # Verify that assignees are not being places after uses of the # assignees in this context. @@ -1088,39 +1088,39 @@ class CodeBuilder(object): for used_variable in inst.get_written_variables(): # Make second (indexed) writes depend on initialization for def_inst_id in context.definition_map.get(used_variable, []): - def_inst = self._instruction_map[def_inst_id] + def_inst = self._statement_map[def_inst_id] if ( not isinstance(def_inst, AssignExpression) or def_inst.assignee_subscript is None): dependencies.add(def_inst_id) - # Add the condition to the instruction. + # Add the condition to the statement. # Update context and global information. - context.context_instruction_ids.add(inst_id) + context.context_statement_ids.add(inst_id) for assignee in inst.get_written_variables(): context.definition_map.setdefault(assignee, set()).add(inst_id) context.used_variables |= inst.get_read_variables() self._all_var_names |= inst.get_written_variables() - self._instruction_map[inst_id] = \ + self._statement_map[inst_id] = \ inst.copy(id=inst_id, depends_on=list(dependencies), condition=self._get_active_condition()) return inst_id def _make_new_context(self, inst, additional_condition=True): """ - :param leading_instructions: A list of lead instruction ids + :param leading_statements: A list of lead statement ids :conditions: A """ - inst_id = self._next_instruction_id() + inst_id = self._next_statement_id() context = self._contexts[-1] new_context = CodeBuilder.Context( - lead_instruction_ids=[inst_id], + lead_statement_ids=[inst_id], used_variables=set(), condition=additional_condition) - self._instruction_map[inst_id] = \ + self._statement_map[inst_id] = \ inst.copy(id=inst_id, - depends_on=inst.depends_on | context.context_instruction_ids, + depends_on=inst.depends_on | context.context_statement_ids, condition=self._get_active_condition()) return new_context @@ -1185,16 +1185,16 @@ class CodeBuilder(object): def __exit__(self, *ignored): self.fence() - self.phase_dependencies = list(self._contexts[-1].lead_instruction_ids) - self.instructions = set(self._instruction_map.values()) + self.phase_dependencies = list(self._contexts[-1].lead_statement_ids) + self.statements = set(self._statement_map.values()) def __str__(self): roots = [ - self._instruction_map[insn_id] + self._statement_map[stmt_id] for ctx in self._contexts - for insn_id in ctx.context_instruction_ids] + for stmt_id in ctx.context_statement_ids] - return "\n".join(_stringify_instructions(roots, self._instruction_map)) + return "\n".join(_stringify_statements(roots, self._statement_map)) def as_execution_phase(self, next_phase): """ @@ -1203,16 +1203,16 @@ class CodeBuilder(object): """ return ExecutionPhase( depends_on=self.phase_dependencies, next_phase=next_phase, - instructions=self.instructions) + statements=self.statements) # }}} # {{{ graphviz / dot export -def get_dot_dependency_graph(code, use_insn_ids=False): +def get_dot_dependency_graph(code, use_stmt_ids=False): """Return a string in the `dot `_ language depicting - dependencies among kernel instructions. + dependencies among kernel statements. """ from pymbolic.imperative.utils import get_dot_dependency_graph @@ -1224,13 +1224,13 @@ def get_dot_dependency_graph(code, use_insn_ids=False): yield dep yield "}" - instructions = [ - insn if use_insn_ids else insn.copy(id=insn.id) + statements = [ + stmt if use_stmt_ids else stmt.copy(id=stmt.id) for phase_name, phase in six.iteritems(code.phases) - for insn in phase.instructions] + for stmt in phase.statements] return get_dot_dependency_graph( - instructions, use_insn_ids=use_insn_ids, + statements, use_stmt_ids=use_stmt_ids, additional_lines_hook=additional_lines_hook) diff --git a/dagrt/transform.py b/dagrt/transform.py index 3930521..2d656c3 100644 --- a/dagrt/transform.py +++ b/dagrt/transform.py @@ -38,7 +38,7 @@ def insert_empty_intermediate_state(dag, phase_name, after_phase): new_phases[after_phase] = new_phases[after_phase].copy( next_phase=phase_name) - return DAGCode(dag.instructions, new_phases, dag.initial_phase) + return DAGCode(dag.statements, new_phases, dag.initial_phase) # }}} @@ -54,15 +54,15 @@ def fuse_two_phases(phase_name, phase1, phase2): % phase_name) from pymbolic.imperative.transform import disambiguate_and_fuse - new_instructions, _, old_2_id_to_new_2_id = disambiguate_and_fuse( - phase1.instructions, phase2.instructions) + new_statements, _, old_2_id_to_new_2_id = disambiguate_and_fuse( + phase1.statements, phase2.statements) return ExecutionPhase( next_phase=phase1.next_phase, depends_on=frozenset(phase1.depends_on) | frozenset( old_2_id_to_new_2_id.get(id2, id2) for id2 in phase2.depends_on), - instructions=new_instructions + statements=new_statements ) elif phase1 is not None: diff --git a/examples/adaptive_rk.py b/examples/adaptive_rk.py index 950d4c1..0daf2ee 100644 --- a/examples/adaptive_rk.py +++ b/examples/adaptive_rk.py @@ -79,7 +79,7 @@ def adaptive_rk_method(tol): cb(t, t + dt_old) return DAGCode.create_with_steady_phase(cb.phase_dependencies, - cb.instructions) + cb.statements) if __name__ == "__main__": from dagrt.codegen import PythonCodeGenerator diff --git a/test/test_ast.py b/test/test_ast.py index aa6c451..f67e0a3 100755 --- a/test/test_ast.py +++ b/test/test_ast.py @@ -27,9 +27,9 @@ from pymbolic import var from pymbolic.primitives import LogicalNot -from dagrt.codegen.dag_ast import (IfThen, IfThenElse, Block, InstructionWrapper, +from dagrt.codegen.dag_ast import (IfThen, IfThenElse, Block, StatementWrapper, create_ast_from_phase, simplify_ast) -from dagrt.language import Instruction, DAGCode +from dagrt.language import Statement, DAGCode import pytest @@ -37,10 +37,10 @@ import pytest def test_create_ast(): x = var("x") - class ComparableNop(Instruction): + class ComparableNop(Statement): """ Works around the fact that __hash__ and comparison isn't defined for - instructions, but is necessary for comparison purposes when embedded + statements, but is necessary for comparison purposes when embedded in an expression. """ @@ -60,7 +60,7 @@ def test_create_ast(): nop = ComparableNop(condition=x, id="nop", depends_on=()) code = DAGCode.create_with_steady_phase(["nop"], [nop]) ast = create_ast_from_phase(code, "main") - assert ast == IfThen(x, InstructionWrapper(nop.copy(condition=True))) + assert ast == IfThen(x, StatementWrapper(nop.copy(condition=True))) _p = var("p") diff --git a/test/test_builtins.py b/test/test_builtins.py index 60c92c9..5a90b40 100755 --- a/test/test_builtins.py +++ b/test/test_builtins.py @@ -53,7 +53,7 @@ def test_len(python_method_impl, obj, len_): cbuild.commit() code = DAGCode.create_with_steady_phase( dep_on=['return'], - instructions=cbuild.instructions) + statements=cbuild.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == len_ @@ -71,7 +71,7 @@ def test_isnan(python_method_impl, value): cbuild.commit() code = DAGCode.create_with_steady_phase( dep_on=['return'], - instructions=cbuild.instructions) + statements=cbuild.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == np.isnan(value) @@ -104,7 +104,7 @@ def test_norm(python_method_impl, order, norm_suffix, test_vector): cbuild.commit() code = DAGCode.create_with_steady_phase( dep_on=['return'], - instructions=cbuild.instructions) + statements=cbuild.statements) result = execute_and_return_single_result(python_method_impl, code) assert np.allclose(result, true_norm(test_vector)) @@ -123,7 +123,7 @@ def test_dot_product(python_method_impl, x, y): cbuild.commit() code = DAGCode.create_with_steady_phase( dep_on=['return'], - instructions=cbuild.instructions) + statements=cbuild.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == np.vdot(x, y) diff --git a/test/test_code_builder.py b/test/test_code_builder.py index b93f826..aa23faa 100755 --- a/test/test_code_builder.py +++ b/test/test_code_builder.py @@ -42,7 +42,7 @@ def test_CodeBuilder_yield(python_method_impl): with CodeBuilder() as builder: builder.yield_state(1, 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 1 @@ -52,7 +52,7 @@ def test_CodeBuilder_assign(python_method_impl): builder(var('x'), 1) builder.yield_state(var('x'), 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 1 @@ -64,7 +64,7 @@ def test_CodeBuilder_condition(python_method_impl): builder(var('x'), 2) builder.yield_state(var('x'), 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 2 @@ -78,7 +78,7 @@ def test_CodeBuilder_condition_with_else(python_method_impl): builder(var('x'), 3) builder.yield_state(var('x'), 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 3 @@ -92,7 +92,7 @@ def test_CodeBuilder_condition_with_else_not_taken(python_method_impl): builder(var('x'), 3) builder.yield_state(var('x'), 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 2 @@ -106,7 +106,7 @@ def test_CodeBuilder_nested_condition(python_method_impl): builder(var('x'), 3) builder.yield_state(var('x'), 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 3 @@ -122,7 +122,7 @@ def test_CodeBuilder_nested_condition_with_else(python_method_impl): builder(var('x'), 4) builder.yield_state(var('x'), 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 4 @@ -138,7 +138,7 @@ def test_CodeBuilder_nested_condition_with_else_not_taken(python_method_impl): builder(var('x'), 4) builder.yield_state(var('x'), 'x', 0, 'final') code = DAGCode.create_with_steady_phase( - builder.phase_dependencies, builder.instructions) + builder.phase_dependencies, builder.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 3 diff --git a/test/test_codegen.py b/test/test_codegen.py index 370a9e0..0835337 100755 --- a/test/test_codegen.py +++ b/test/test_codegen.py @@ -59,7 +59,7 @@ def test_circular_dependency_detection(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) with pytest.raises(CodeGenerationError): verify_code(code) @@ -67,7 +67,7 @@ def test_circular_dependency_detection(): def test_missing_dependency_detection(): """Check that the code generator detects that there is a missing dependency.""" - instructions = set([ + statements = set([ AssignExpression(id='assign', assignee='y', assignee_subscript=(), expression=1, depends_on=['assign2']), YieldState(id='return', time=0, time_id='final', @@ -76,7 +76,7 @@ def test_missing_dependency_detection(): ]) code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=instructions, step_dep_on=['return']) + statements=statements, step_dep_on=['return']) with pytest.raises(CodeGenerationError): verify_code(code) @@ -89,7 +89,7 @@ def test_missing_state_detection(): cb.phase_transition("state_2") code = DAGCode.create_with_steady_phase( - dep_on=cb.phase_dependencies, instructions=cb.instructions) + dep_on=cb.phase_dependencies, statements=cb.statements) with pytest.raises(CodeGenerationError): verify_code(code) @@ -118,7 +118,7 @@ def test_cond_detection(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) with pytest.raises(CodeGenerationError): verify_code(code) diff --git a/test/test_codegen_fortran.py b/test/test_codegen_fortran.py index e5b6cb3..3e690c0 100755 --- a/test/test_codegen_fortran.py +++ b/test/test_codegen_fortran.py @@ -54,7 +54,7 @@ def test_basic_codegen(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) codegen = f.CodeGenerator("simple", user_type_map={ "state": f.ArrayType( @@ -100,7 +100,7 @@ def test_arrays_and_linalg(): cb.raise_(MatrixInversionFailure) code = DAGCode.create_with_steady_phase( - cb.phase_dependencies, cb.instructions) + cb.phase_dependencies, cb.statements) codegen = f.CodeGenerator( 'arrays', diff --git a/test/test_codegen_python.py b/test/test_codegen_python.py index b85c02c..69c1e86 100755 --- a/test/test_codegen_python.py +++ b/test/test_codegen_python.py @@ -50,7 +50,7 @@ def test_basic_codegen(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) codegen = PythonCodeGenerator(class_name='Method') Method = codegen.get_class(code) # noqa method = Method({}) @@ -84,7 +84,7 @@ def test_basic_conditional_codegen(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) codegen = PythonCodeGenerator(class_name='Method') Method = codegen.get_class(code) # noqa method = Method({}) @@ -118,7 +118,7 @@ def test_basic_assign_rhs_codegen(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) codegen = PythonCodeGenerator(class_name='Method') Method = codegen.get_class(code) # noqa @@ -138,7 +138,7 @@ def test_basic_assign_rhs_codegen(): def test_basic_raise_codegen(): - """Test code generation of the Raise instruction.""" + """Test code generation of the Raise statement.""" cbuild = RawCodeBuilder() class TimeStepUnderflow(RuntimeError): @@ -148,7 +148,7 @@ def test_basic_raise_codegen(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=["raise"]) + statements=cbuild.statements, step_dep_on=["raise"]) codegen = PythonCodeGenerator(class_name="Method") Method = codegen.get_class(code) # noqa method = Method({}) @@ -167,13 +167,13 @@ def test_basic_raise_codegen(): def test_basic_fail_step_codegen(): - """Test code generation of the FailStep instruction.""" + """Test code generation of the FailStep statement.""" cbuild = RawCodeBuilder() cbuild.add_and_get_ids(FailStep(id="fail")) cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=["fail"]) + statements=cbuild.statements, step_dep_on=["fail"]) codegen = PythonCodeGenerator(class_name="Method") Method = codegen.get_class(code) # noqa method = Method({}) @@ -204,7 +204,7 @@ def test_local_name_distinctness(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) codegen = PythonCodeGenerator(class_name='Method') Method = codegen.get_class(code) # noqa method = Method({}) @@ -231,7 +231,7 @@ def test_global_name_distinctness(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) codegen = PythonCodeGenerator(class_name='Method') Method = codegen.get_class(code) # noqa method = Method({}) @@ -252,7 +252,7 @@ def test_function_name_distinctness(): cbuild.commit() code = DAGCode._create_with_init_and_step( initialization_dep_on=[], - instructions=cbuild.instructions, step_dep_on=['return']) + statements=cbuild.statements, step_dep_on=['return']) codegen = PythonCodeGenerator(class_name='Method') Method = codegen.get_class(code) # noqa method = Method({'y^': lambda: 0, @@ -277,10 +277,10 @@ def test_phase_transitions(python_method_impl): phases={ "state_1": ExecutionPhase( builder_1.phase_dependencies, next_phase="state_1", - instructions=builder_1.instructions), + statements=builder_1.statements), "state_2": ExecutionPhase( builder_2.phase_dependencies, next_phase="state_2", - instructions=builder_2.instructions) + statements=builder_2.statements) }, initial_phase="state_1") from utils import execute_and_return_single_result @@ -308,7 +308,7 @@ def get_IfThenElse_test_code_and_expected_result(): "result", 0, "final") code = DAGCode.create_with_steady_phase( - cb.phase_dependencies, cb.instructions) + cb.phase_dependencies, cb.statements) return (code, (0, 1, 0, 1, 0, 1, 1, 2, 1, 2)) @@ -339,7 +339,7 @@ def test_arrays_and_looping(python_method_impl): from utils import execute_and_return_single_result code = DAGCode.create_with_steady_phase( - cb.phase_dependencies, cb.instructions) + cb.phase_dependencies, cb.statements) result = execute_and_return_single_result(python_method_impl, code) assert result == 15 @@ -375,7 +375,7 @@ def test_arrays_and_linalg(python_method_impl): from utils import execute_and_return_single_result code = DAGCode.create_with_steady_phase( - cb.phase_dependencies, cb.instructions) + cb.phase_dependencies, cb.statements) result = execute_and_return_single_result(python_method_impl, code) result = result.reshape(4, 4, order="F") @@ -418,7 +418,7 @@ def test_svd(python_method_impl): from utils import execute_and_return_single_result code = DAGCode.create_with_steady_phase( - cb.phase_dependencies, cb.instructions) + cb.phase_dependencies, cb.statements) result = execute_and_return_single_result(python_method_impl, code) assert la.norm(result) < 1e-10 diff --git a/test/utils.py b/test/utils.py index 02df0cd..a56b16f 100644 --- a/test/utils.py +++ b/test/utils.py @@ -64,11 +64,11 @@ class RawCodeBuilder(object): self.id_set = set() self.generated_id_set = set() - self._instructions = [] + self._statements = [] self.build_group = [] - def fresh_insn_id(self, prefix): - """Return an instruction name that is guaranteed not to be in use and + def fresh_stmt_id(self, prefix): + """Return an statement name that is guaranteed not to be in use and not to be generated in the future.""" from pytools import generate_unique_names for possible_id in generate_unique_names(prefix): @@ -77,45 +77,45 @@ class RawCodeBuilder(object): self.generated_id_set.add(possible_id) return possible_id - def add_and_get_ids(self, *insns): + def add_and_get_ids(self, *stmts): new_ids = [] - for insn in insns: + for stmt in stmts: set_attrs = {} - if not hasattr(insn, "id") or insn.id is None: - set_attrs["id"] = self.fresh_insn_id("insn") + if not hasattr(stmt, "id") or stmt.id is None: + set_attrs["id"] = self.fresh_stmt_id("stmt") else: - if insn.id in self.id_set: + if stmt.id in self.id_set: raise ValueError("duplicate ID") - if not hasattr(insn, "depends_on"): + if not hasattr(stmt, "depends_on"): set_attrs["depends_on"] = frozenset() if set_attrs: - insn = insn.copy(**set_attrs) + stmt = stmt.copy(**set_attrs) - self.build_group.append(insn) - new_ids.append(insn.id) + self.build_group.append(stmt) + new_ids.append(stmt.id) # For exception safety, only make state change at end. self.id_set.update(new_ids) return new_ids def commit(self): - for insn in self.build_group: - for dep in insn.depends_on: + for stmt in self.build_group: + for dep in stmt.depends_on: if dep not in self.id_set: raise ValueError("unknown dependency id: %s" % dep) - self._instructions.extend(self.build_group) + self._statements.extend(self.build_group) del self.build_group[:] @property - def instructions(self): + def statements(self): if self.build_group: - raise ValueError("attempted to get instructions while " + raise ValueError("attempted to get statements while " "build group is uncommitted") - return self._instructions + return self._statements # }}} -- GitLab