From ee904a355fa986b4c46c7729f6b2103a11cd7503 Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Thu, 1 Mar 2018 19:54:50 -0600 Subject: [PATCH 1/5] Realize "state" to "phase" rename for state-machine "states". This commit does not fix everything in dagrt.codegen.fortan --- dagrt/codegen/analysis.py | 68 +++++++++---------- dagrt/codegen/ast.py | 12 ++-- dagrt/codegen/fortran.py | 36 +++++----- dagrt/codegen/python.py | 50 +++++++------- dagrt/codegen/transform.py | 40 +++++------ dagrt/exec_numpy.py | 26 ++++---- dagrt/language.py | 125 ++++++++++++++++++----------------- dagrt/transform.py | 30 ++++----- examples/adaptive_rk.py | 2 +- test/test_ast.py | 6 +- test/test_builtins.py | 8 +-- test/test_code_builder.py | 36 +++++----- test/test_codegen.py | 6 +- test/test_codegen_fortran.py | 4 +- test/test_codegen_python.py | 38 +++++------ 15 files changed, 244 insertions(+), 243 deletions(-) diff --git a/dagrt/codegen/analysis.py b/dagrt/codegen/analysis.py index 6c86418..5b8789c 100644 --- a/dagrt/codegen/analysis.py +++ b/dagrt/codegen/analysis.py @@ -24,7 +24,7 @@ THE SOFTWARE. import six from pymbolic.mapper import Collector -from dagrt.language import YieldState, StateTransition, AssignFunctionCall +from dagrt.language import YieldState, PhaseTransition, AssignFunctionCall # {{{ verifier @@ -34,54 +34,54 @@ def _quote(string): return "\"{0}\"".format(string) -def verify_state_transitions(states, errors): +def verify_phase_transitions(phases, errors): """ - Ensure that states referenced by StateTransition exist. + Ensure that phases referenced by PhaseTransition exist. :arg instructions: A set of instructions to verify - :arg states: A map from state names to states + :arg phases: A map from phase names to phases :arg errors: An error list to which new errors get appended """ - state_names = [key for key in states.keys()] - for state in six.itervalues(states): - for inst in state.instructions: - if not isinstance(inst, StateTransition): + phase_names = [key for key in phases.keys()] + for phase in six.itervalues(phases): + for inst in phase.instructions: + if not isinstance(inst, PhaseTransition): continue - if inst.next_state not in state_names: + if inst.next_phase not in phase_names: errors.append( - "State \"{0}\" referenced by instruction \"{1}:{2}\" not found" - .format(inst.next_state, state, inst)) + "Phase \"{0}\" referenced by instruction \"{1}:{2}\" not found" + .format(inst.next_phase, phase, inst)) -def verify_all_dependencies_exist(states, errors): +def verify_all_dependencies_exist(phases, errors): """ Ensure that all instruction dependencies exist. :arg instructions: A set of instructions to verify - :arg states: A map from state names to states + :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 state in six.itervalues(states) - for inst in state.instructions) + for phase in six.itervalues(phases) + for inst in phase.instructions) # Check instructions - for state in six.itervalues(states): - for inst in state.instructions: + for phase in six.itervalues(phases): + for inst in phase.instructions: deps = set(inst.depends_on) if not deps <= ids: errors.extend( ["Dependency \"{0}\" referenced by instruction \"{1}\" not found" .format(dep_name, inst) for dep_name in deps - ids]) - # Check states. - for state_name, state in six.iteritems(states): - deps = set(state.depends_on) + # Check phases. + for phase_name, phase in six.iteritems(phases): + deps = set(phase.depends_on) if not deps <= ids: errors.extend( - ["Dependencies {0} referenced by state \"{1}\" not found" + ["Dependencies {0} referenced by phase \"{1}\" not found" .format(", ".join(_quote(dep) for dep in ids - deps), - state_name)]) + phase_name)]) def verify_no_circular_dependencies(instructions, errors): @@ -153,14 +153,14 @@ def verify_code(code): try: # Wrap in a try block, since some verifier passes may fail due to badly # malformed code. - verify_all_dependencies_exist(code.states, errors) - for state in six.itervalues(code.states): - verify_no_circular_dependencies(state.instructions, errors) + verify_all_dependencies_exist(code.phases, errors) + for phase in six.itervalues(code.phases): + verify_no_circular_dependencies(phase.instructions, errors) - verify_state_transitions(code.states, errors) + verify_phase_transitions(code.phases, errors) - for state in six.itervalues(code.states): - verify_single_definition_cond_rule(state.instructions, errors) + for phase in six.itervalues(code.phases): + verify_single_definition_cond_rule(phase.instructions, errors) except Exception as e: # Ensure there is at least one error to report. @@ -205,8 +205,8 @@ def collect_function_names_from_dag(dag, no_expressions=False): def mapper(expr): result.update(fnc(expr)) return expr - for state in six.itervalues(dag.states): - for insn in state.instructions: + for phase in six.itervalues(dag.phases): + for insn in phase.instructions: if isinstance(insn, AssignFunctionCall): result.add(insn.function_id) @@ -223,8 +223,8 @@ def collect_function_names_from_dag(dag, no_expressions=False): def collect_time_ids_from_dag(dag): result = set() - for state in six.itervalues(dag.states): - for insn in state.instructions: + for phase in six.itervalues(dag.phases): + for insn in phase.instructions: if isinstance(insn, YieldState): result.add(insn.time_id) @@ -238,8 +238,8 @@ def collect_time_ids_from_dag(dag): def collect_ode_component_names_from_dag(dag): result = set() - for state in six.itervalues(dag.states): - for insn in state.instructions: + for phase in six.itervalues(dag.phases): + for insn in phase.instructions: if isinstance(insn, YieldState): result.add(insn.component_id) diff --git a/dagrt/codegen/ast.py b/dagrt/codegen/ast.py index 2ad0895..bd855b9 100644 --- a/dagrt/codegen/ast.py +++ b/dagrt/codegen/ast.py @@ -130,24 +130,24 @@ def get_instructions_in_ast(ast): yield inst -def create_ast_from_state(code, state_name): +def create_ast_from_phase(code, phase_name): """ - Return an AST representation of the instructions corresponding to the state - named `state` as found in the :class:`DAGCode` instance `code`. + Return an AST representation of the instructions corresponding to the phase + named `phase` as found in the :class:`DAGCode` instance `code`. """ - state = code.states[state_name] + phase = code.phases[phase_name] # Construct a topological order of the instructions. stack = [] - instruction_map = dict((inst.id, inst) for inst in state.instructions) + instruction_map = dict((inst.id, inst) for inst in phase.instructions) visiting = set() visited = set() topological_order = [] # TODO: Clump nodes together in the topological order based on conditionals. - stack.extend(sorted(state.depends_on)) + stack.extend(sorted(phase.depends_on)) while stack: instruction = stack[-1] if instruction in visited: diff --git a/dagrt/codegen/fortran.py b/dagrt/codegen/fortran.py index 83cfaab..2685456 100644 --- a/dagrt/codegen/fortran.py +++ b/dagrt/codegen/fortran.py @@ -1046,15 +1046,15 @@ class CodeGenerator(StructuredCodeGenerator): # {{{ produce function name / function AST pairs - from .ast import create_ast_from_state + from .ast import create_ast_from_phase from collections import namedtuple NameASTPair = namedtuple("NameASTPair", "name, ast") # noqa fdescrs = [] - for state_name in sorted(six.iterkeys(dag.states)): - ast = create_ast_from_state(dag, state_name) - fdescrs.append(NameASTPair(state_name, ast)) + for phase_name in sorted(six.iterkeys(dag.phases)): + ast = create_ast_from_phase(dag, phase_name) + fdescrs.append(NameASTPair(phase_name, ast)) # }}} @@ -1213,7 +1213,7 @@ class CodeGenerator(StructuredCodeGenerator): # {{{ state name constants - for i, state in enumerate(sorted(dag.states)): + for i, state in enumerate(sorted(dag.phases)): state_sym_name = self.state_name_to_state_sym(state) self.emit("integer {state_sym_name}".format( state_sym_name=state_sym_name)) @@ -1247,7 +1247,7 @@ class CodeGenerator(StructuredCodeGenerator): self.emitter, 'dagrt_state_type', self) as emit: - emit('integer dagrt_next_state') + emit('integer dagrt_next_phase') emit('') for identifier, sym_kind in sorted(six.iteritems( @@ -1265,7 +1265,7 @@ class CodeGenerator(StructuredCodeGenerator): emit('! {{{ instrumentation') emit('') - for state_name in sorted(dag.states): + for state_name in sorted(dag.phases): emit('integer dagrt_state_%s_count' % state_name) emit('integer dagrt_state_%s_failures' % state_name) emit('real*8 dagrt_state_%s_time' % state_name) @@ -1644,8 +1644,8 @@ class CodeGenerator(StructuredCodeGenerator): self.emit("read(dagrt_nan_str,*) dagrt_nan") self.emit( - "dagrt_state%dagrt_next_state = dagrt_state_{0}" - .format(dag.initial_state)) + "dagrt_state%dagrt_next_phase = dagrt_state_{0}" + .format(dag.initial_phase)) for sym, sym_kind in sorted(six.iteritems( self.sym_kind_table.global_table)): @@ -1707,7 +1707,7 @@ class CodeGenerator(StructuredCodeGenerator): self.emit('! {{{ instrumentation') self.emit('') - for state_name in sorted(dag.states): + for state_name in sorted(dag.phases): self.emit('dagrt_state%%dagrt_state_%s_count = 0' % state_name) self.emit('dagrt_state%%dagrt_state_%s_failures = 0' % state_name) self.emit('dagrt_state%%dagrt_state_%s_time = 0' % state_name) @@ -1784,9 +1784,9 @@ class CodeGenerator(StructuredCodeGenerator): self.current_function = state_id if_emit = None - for name, state_descr in sorted(six.iteritems(dag.states)): + for name, state_descr in sorted(six.iteritems(dag.phases)): state_sym_name = self.state_name_to_state_sym(name) - cond = "dagrt_state%dagrt_next_state == "+state_sym_name + cond = "dagrt_state%dagrt_next_phase == "+state_sym_name if if_emit is None: if_emit = FortranIfEmitter( @@ -1796,8 +1796,8 @@ class CodeGenerator(StructuredCodeGenerator): if_emit.emit_else_if(cond) self.emit( - "dagrt_state%dagrt_next_state = " - + self.state_name_to_state_sym(state_descr.next_state)) + "dagrt_state%dagrt_next_phase = " + + self.state_name_to_state_sym(state_descr.next_phase)) self.emit( "call dagrt_state_func_{state_name}({args})".format( @@ -1807,7 +1807,7 @@ class CodeGenerator(StructuredCodeGenerator): if if_emit: if_emit.emit_else() self.emit("write(dagrt_stderr,*) 'encountered invalid state in run', " - "dagrt_state%dagrt_next_state") + "dagrt_state%dagrt_next_phase") self.emit("stop") if_emit.__exit__(None, None, None) @@ -1835,7 +1835,7 @@ class CodeGenerator(StructuredCodeGenerator): self.emit("write(*,*) 'dagrt profile information'") self.emit("write(*,*) '%s'" % delim) - for state_name in sorted(dag.states): + for state_name in sorted(dag.phases): self.emit( "write(*,*) 'state {state} count:', " "dagrt_state%dagrt_state_{state}_count" @@ -2255,8 +2255,8 @@ class CodeGenerator(StructuredCodeGenerator): def emit_inst_StateTransition(self, inst): self.emit( - 'dagrt_state%dagrt_next_state = ' - + self.state_name_to_state_sym(inst.next_state)) + 'dagrt_state%dagrt_next_phase = ' + + self.state_name_to_state_sym(inst.next_phase)) # }}} diff --git a/dagrt/codegen/python.py b/dagrt/codegen/python.py index 05b803b..b02c758 100644 --- a/dagrt/codegen/python.py +++ b/dagrt/codegen/python.py @@ -61,7 +61,7 @@ class StateComputed(namedtuple("StateComputed", class StepCompleted( namedtuple("StepCompleted", - ["dt", "t", "current_state", "next_state"])): + ["dt", "t", "current_phase", "next_phase"])): """ .. attribute:: dt @@ -71,8 +71,8 @@ class StepCompleted( Approximate integrator time at end of step. - .. attribute:: current_state - .. attribute:: next_state + .. attribute:: current_phase + .. attribute:: next_phase """ class StepFailed(namedtuple("StepFailed", ["t"])): @@ -97,8 +97,8 @@ class ExitStepException(RuntimeError): class TransitionEvent(Exception): - def __init__(self, next_state): - self.next_state = next_state + def __init__(self, next_phase): + self.next_phase = next_phase class StepError(Exception): @@ -206,13 +206,13 @@ class CodeGenerator(StructuredCodeGenerator): from .analysis import verify_code verify_code(dag) - from .ast import create_ast_from_state + from .ast import create_ast_from_phase self.begin_emit(dag) - for state_name in six.iterkeys(dag.states): - ast = create_ast_from_state(dag, state_name) + for phase_name in six.iterkeys(dag.phases): + ast = create_ast_from_phase(dag, phase_name) self._pre_lower(ast) - self.lower_function(state_name, ast) + self.lower_function(phase_name, ast) self.finish_emit(dag) return self.get_code() @@ -289,11 +289,11 @@ class CodeGenerator(StructuredCodeGenerator): py_function_id=py_function_id, function_id=function_id)) emit("") - emit("self.state_transition_table = "+repr(dict( - (state_name, ( - state.next_state, - BareExpression("self.state_"+state_name))) - for state_name, state in six.iteritems(dag.states)))) + emit("self.phase_transition_table = "+repr(dict( + (phase_name, ( + phase.next_phase, + BareExpression("self.phase_"+phase_name))) + for phase_name, phase in six.iteritems(dag.phases)))) emit("") self._class_emitter.incorporate(emit) @@ -313,7 +313,7 @@ class CodeGenerator(StructuredCodeGenerator): emit('{component} = context.get("{component_id}")'.format( component=component, component_id=component_id)) - emit("self.next_state = "+repr(dag.initial_state)) + emit("self.next_phase = "+repr(dag.initial_phase)) emit("") self._class_emitter.incorporate(emit) @@ -329,7 +329,7 @@ class CodeGenerator(StructuredCodeGenerator): if max_steps is not None and n_steps >= max_steps: return - cur_state = self.next_state + cur_phase = self.next_phase try: for evt in self.run_single_step(): yield evt @@ -342,10 +342,10 @@ class CodeGenerator(StructuredCodeGenerator): continue except self.TransitionEvent as evt: - self.next_state = evt.next_state + self.next_phase = evt.next_phase yield self.StepCompleted(dt=self.dt, t=self.t, - current_state=cur_state, next_state=self.next_state) + current_phase=cur_phase, next_phase=self.next_phase) n_steps += 1 """) @@ -356,10 +356,10 @@ class CodeGenerator(StructuredCodeGenerator): emit = PythonFunctionEmitter('run_single_step', ('self',)) emit(""" - self.next_state, state_func = ( - self.state_transition_table[self.next_state]) + self.next_phase, phase_func = ( + self.phase_transition_table[self.next_phase]) - for evt in state_func(): + for evt in phase_func(): yield evt """) self._class_emitter.incorporate(emit) @@ -374,7 +374,7 @@ class CodeGenerator(StructuredCodeGenerator): return self._class_emitter.get() def emit_def_begin(self, name): - self._emitter = PythonFunctionEmitter('state_' + name, ('self',)) + self._emitter = PythonFunctionEmitter('phase_' + name, ('self',)) self._name_manager.clear_locals() def emit_def_end(self): @@ -487,9 +487,9 @@ class CodeGenerator(StructuredCodeGenerator): if not self._has_yield_inst: self._emit('yield') - def emit_inst_StateTransition(self, inst): - assert '\'' not in inst.next_state - self._emit('raise self.TransitionEvent(\'' + inst.next_state + '\')') + def emit_inst_PhaseTransition(self, inst): + assert '\'' not in inst.next_phase + self._emit('raise self.TransitionEvent(\'' + inst.next_phase + '\')') if not self._has_yield_inst: self._emit('yield') diff --git a/dagrt/codegen/transform.py b/dagrt/codegen/transform.py index 58cbb98..b05ce55 100644 --- a/dagrt/codegen/transform.py +++ b/dagrt/codegen/transform.py @@ -34,10 +34,10 @@ def eliminate_self_dependencies(dag): insn_id_gen = dag.get_insn_id_generator() var_name_gen = dag.get_var_name_generator() - new_states = {} - for state_name, state in six.iteritems(dag.states): + new_phases = {} + for phase_name, phase in six.iteritems(dag.phases): new_instructions = [] - for insn in sorted(state.instructions, key=lambda insn: insn.id): + for insn in sorted(phase.instructions, key=lambda insn: insn.id): read_and_written = ( insn.get_read_variables() & insn.get_written_variables()) @@ -77,9 +77,9 @@ def eliminate_self_dependencies(dag): new_instructions.append(new_insn) - new_states[state_name] = state.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(instructions=new_instructions) - return dag.copy(states=new_states) + return dag.copy(phases=new_phases) # }}} @@ -143,8 +143,8 @@ def isolate_function_arguments(dag): insn_id_gen = dag.get_insn_id_generator() var_name_gen = dag.get_var_name_generator() - new_states = {} - for state_name, state in six.iteritems(dag.states): + new_phases = {} + for phase_name, phase in six.iteritems(dag.phases): new_instructions = [] fai = FunctionArgumentIsolator( @@ -152,7 +152,7 @@ def isolate_function_arguments(dag): insn_id_gen=insn_id_gen, var_name_gen=var_name_gen) - for insn in sorted(state.instructions, key=lambda insn: insn.id): + for insn in sorted(phase.instructions, key=lambda insn: insn.id): base_deps = insn.depends_on new_deps = [] @@ -163,9 +163,9 @@ def isolate_function_arguments(dag): expr, insn.condition, base_deps, new_deps)) .copy(depends_on=insn.depends_on | frozenset(new_deps))) - new_states[state_name] = state.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(instructions=new_instructions) - return dag.copy(states=new_states) + return dag.copy(phases=new_phases) # }}} @@ -241,8 +241,8 @@ def isolate_function_calls(dag): insn_id_gen = dag.get_insn_id_generator() var_name_gen = dag.get_var_name_generator() - new_states = {} - for state_name, state in six.iteritems(dag.states): + new_phases = {} + for phase_name, phase in six.iteritems(dag.phases): new_instructions = [] fci = FunctionCallIsolator( @@ -250,7 +250,7 @@ def isolate_function_calls(dag): insn_id_gen=insn_id_gen, var_name_gen=var_name_gen) - for insn in sorted(state.instructions, key=lambda insn: insn.id): + for insn in sorted(phase.instructions, key=lambda insn: insn.id): new_deps = [] from dagrt.language import AssignExpression @@ -267,9 +267,9 @@ def isolate_function_calls(dag): else: new_instructions.append(insn) - new_states[state_name] = state.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(instructions=new_instructions) - return dag.copy(states=new_states) + return dag.copy(phases=new_phases) # }}} @@ -361,8 +361,8 @@ def expand_IfThenElse(dag): # noqa insn_id_gen = dag.get_insn_id_generator() var_name_gen = dag.get_var_name_generator() - new_states = {} - for state_name, state in six.iteritems(dag.states): + new_phases = {} + for phase_name, phase in six.iteritems(dag.phases): new_instructions = [] expander = IfThenElseExpander( @@ -370,7 +370,7 @@ def expand_IfThenElse(dag): # noqa insn_id_gen=insn_id_gen, var_name_gen=var_name_gen) - for insn in state.instructions: + for insn in phase.instructions: base_deps = insn.depends_on new_deps = [] @@ -379,9 +379,9 @@ def expand_IfThenElse(dag): # noqa lambda expr: expander(expr, insn.condition, base_deps, new_deps)) .copy(depends_on=insn.depends_on | frozenset(new_deps))) - new_states[state_name] = state.copy(instructions=new_instructions) + new_phases[phase_name] = phase.copy(instructions=new_instructions) - return dag.copy(states=new_states) + return dag.copy(phases=new_phases) # }}} diff --git a/dagrt/exec_numpy.py b/dagrt/exec_numpy.py index dd24c73..ce9edc9 100644 --- a/dagrt/exec_numpy.py +++ b/dagrt/exec_numpy.py @@ -37,8 +37,8 @@ class ExitStepException(Exception): class TransitionEvent(Exception): - def __init__(self, next_state): - self.next_state = next_state + def __init__(self, next_phase): + self.next_phase = next_phase # {{{ events returned from NumpyInterpreter.run() @@ -58,7 +58,7 @@ class StateComputed(namedtuple("StateComputed", class StepCompleted( namedtuple("StepCompleted", - ["dt", "t", "current_state", "next_state"])): + ["dt", "t", "current_state", "next_phase"])): """ .. attribute:: dt @@ -69,7 +69,7 @@ class StepCompleted( Approximate integrator time at end of step. .. attribute:: current_state - .. attribute:: next_state + .. attribute:: next_phase """ @@ -88,7 +88,7 @@ class NumpyInterpreter(object): """A :mod:`numpy`-targeting interpreter for the time integration language defined in :mod:`dagrt.language`. - .. attribute:: next_state + .. attribute:: next_phase .. automethod:: set_up .. automethod:: run @@ -108,7 +108,7 @@ class NumpyInterpreter(object): from dagrt.language import ExecutionController self.exec_controller = ExecutionController(code) self.context = {} - self.next_state = self.code.initial_state + self.next_phase = self.code.initial_phase from dagrt.builtins_python import builtins @@ -143,7 +143,7 @@ class NumpyInterpreter(object): if max_steps is not None and n_steps >= max_steps: return - cur_state = self.next_state + cur_state = self.next_phase try: for evt in self.run_single_step(): yield evt @@ -157,21 +157,21 @@ class NumpyInterpreter(object): continue except TransitionEvent as evt: - self.next_state = evt.next_state + self.next_phase = evt.next_phase yield StepCompleted( dt=self.context["
"], t=self.context[""], current_state=cur_state, - next_state=self.next_state) + next_phase=self.next_phase) n_steps += 1 def run_single_step(self): try: self.exec_controller.reset() - cur_state = self.code.states[self.next_state] - self.next_state = cur_state.next_state + cur_state = self.code.phases[self.next_phase] + self.next_phase = cur_state.next_phase self.exec_controller.update_plan(cur_state, cur_state.depends_on) for event in self.exec_controller(cur_state, self): yield event @@ -275,8 +275,8 @@ class NumpyInterpreter(object): def exec_Nop(self, insn): pass - def exec_StateTransition(self, insn): - raise TransitionEvent(insn.next_state) + def exec_PhaseTransition(self, insn): + raise TransitionEvent(insn.next_phase) # }}} diff --git a/dagrt/language.py b/dagrt/language.py index e2cede5..4441ff5 100644 --- a/dagrt/language.py +++ b/dagrt/language.py @@ -110,18 +110,19 @@ Assignment Instructions .. autoclass:: AssignExpression .. autoclass:: AssignFunctionCall -State Instructions -^^^^^^^^^^^^^^^^^^ +Control Instructions +^^^^^^^^^^^^^^^^^^^^ .. autoclass:: YieldState .. autoclass:: Raise .. autoclass:: FailStep .. autoclass:: ExitStep +.. autoclass:: PhaseTransition Code Container ~~~~~~~~~~~~~~ -.. autoclass:: ExecutionState +.. autoclass:: ExecutionPhase .. autoclass:: DAGCode Visualization @@ -545,24 +546,24 @@ class Raise(Instruction): exec_method = six.moves.intern("exec_Raise") -class StateTransition(Instruction): +class PhaseTransition(Instruction): """ - .. attribute:: next_state + .. attribute:: next_phase The name of the next state to enter """ - def __init__(self, next_state, **kwargs): - Instruction.__init__(self, next_state=next_state, **kwargs) + def __init__(self, next_phase, **kwargs): + Instruction.__init__(self, next_phase=next_phase, **kwargs) def get_written_variables(self): return frozenset() def __str__(self): - return "Transition to {state}{cond}".format(state=self.next_state, + return "Transition to {state}{cond}".format(state=self.next_phase, cond=self._condition_printing_suffix()) - exec_method = six.moves.intern("exec_StateTransition") + exec_method = six.moves.intern("exec_PhaseTransition") class FailStep(Instruction): @@ -596,14 +597,14 @@ class ExitStep(Instruction): # {{{ code container -class ExecutionState(RecordWithoutPickling): +class ExecutionPhase(RecordWithoutPickling): """ .. attribute:: depends_on a list of instruction IDs that need to be accomplished for successful execution of one round of this state - .. attribute:: next_state + .. attribute:: next_phase name of the next state after this one, if no other state is specified by the user. @@ -616,10 +617,10 @@ class ExecutionState(RecordWithoutPickling): will actually be executed. """ - def __init__(self, depends_on, next_state, instructions): - super(ExecutionState, self).__init__( + def __init__(self, depends_on, next_phase, instructions): + super(ExecutionPhase, self).__init__( depends_on=depends_on, - next_state=next_state, + next_phase=next_phase, instructions=instructions) @property @@ -631,43 +632,43 @@ class ExecutionState(RecordWithoutPickling): class DAGCode(RecordWithoutPickling): """ - .. attribute:: states + .. attribute:: phases - is a map from time integrator state names to :class:`ExecutionState` + is a map from time integrator state names to :class:`ExecutionPhase` instances - .. attribute:: initial_state + .. attribute:: initial_phase the name of the starting state """ @classmethod - def create_with_steady_state(cls, dep_on, instructions): - states = {'main': ExecutionState( - dep_on, next_state='main', instructions=instructions)} - return cls(states, 'main') + def create_with_steady_phase(cls, dep_on, instructions): + phases = {'main': ExecutionPhase( + dep_on, next_phase='main', instructions=instructions)} + return cls(phases, 'main') @classmethod def _create_with_init_and_step(cls, initialization_dep_on, step_dep_on, instructions): - states = {} - states['initialization'] = ExecutionState( + phases = {} + phases['initialization'] = ExecutionPhase( initialization_dep_on, - next_state='primary', + next_phase='primary', instructions=instructions) - states['primary'] = ExecutionState( + phases['primary'] = ExecutionPhase( step_dep_on, - next_state='primary', + next_phase='primary', instructions=instructions) - return cls(states, 'initialization') + return cls(phases, 'initialization') - def __init__(self, states, initial_state): - assert not isinstance(states, list) + def __init__(self, phases, initial_phase): + assert not isinstance(phases, list) RecordWithoutPickling.__init__(self, - states=states, - initial_state=initial_state) + phases=phases, + initial_phase=initial_phase) # {{{ identifier wrangling @@ -675,12 +676,12 @@ class DAGCode(RecordWithoutPickling): from pytools import UniqueNameGenerator return UniqueNameGenerator( set(insn.id - for state in six.itervalues(self.states) - for insn in state.instructions)) + for phase in six.itervalues(self.phases) + for insn in phase.instructions)) def existing_var_names(self): result = set() - for state in six.itervalues(self.states): + for state in six.itervalues(self.phases): for insn in state.instructions: result.update(insn.get_written_variables()) result.update(insn.get_read_variables()) @@ -695,15 +696,15 @@ class DAGCode(RecordWithoutPickling): def __str__(self): lines = [] - for state_name, state in sorted(six.iteritems(self.states)): - lines.append("STATE %s" % state_name) + for phase_name, phase in sorted(six.iteritems(self.phases)): + lines.append("STAGE %s" % phase_name) - for root_id in state.depends_on: + for root_id in phase.depends_on: lines.extend(_stringify_instructions( - [state.id_to_insn[root_id]], - state.id_to_insn, prefix=" ")) + [phase.id_to_insn[root_id]], + phase.id_to_insn, prefix=" ")) - lines.append(" -> (next state) %s" % state.next_state) + lines.append(" -> (next phase) %s" % phase.next_phase) lines.append("") return "\n".join(lines) @@ -729,7 +730,7 @@ class ExecutionController(object): self.plan_id_set.clear() self.executed_ids.clear() - def update_plan(self, state, execute_ids): + 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 others and such that all their dependencies are satisfied. @@ -737,7 +738,7 @@ class ExecutionController(object): early_plan = [] - id_to_insn = state.id_to_insn + id_to_insn = phase.id_to_insn def add_with_deps(insn): insn_id = insn.id @@ -765,8 +766,8 @@ class ExecutionController(object): self.plan = early_plan + self.plan self.plan_id_set.update(early_plan) - def __call__(self, state, target): - id_to_insn = state.id_to_insn + def __call__(self, phase, target): + id_to_insn = phase.id_to_insn while self.plan: insn_id = self.plan.pop(0) @@ -789,7 +790,7 @@ class ExecutionController(object): yield event if new_deps is not None: - self.update_plan(state, new_deps) + self.update_plan(phase, new_deps) # }}} @@ -800,12 +801,12 @@ class CodeBuilder(object): """ .. attribute:: instructions - The set of instructions generated for the state + The set of instructions generated for the phase - .. attribute:: state_dependencies + .. attribute:: phase_dependencies A list of instruction names. Starting with these instructions - as the root dependencies, the state can be executed by following + as the root dependencies, the phase can be executed by following the dependency list of each instruction. .. automethod:: fence @@ -820,7 +821,7 @@ class CodeBuilder(object): .. automethod:: fail_step .. automethod:: exit_step .. automethod:: raise_ - .. automethod:: state_transition + .. automethod:: phase_transition .. automethod:: __enter__ """ @@ -848,9 +849,9 @@ class CodeBuilder(object): used_variables=set(used_variables), condition=condition) - def __init__(self, label="state"): + def __init__(self, label="phase"): """ - :arg label: The name of the state to generate + :arg label: The name of the phase to generate """ self.label = label self._instruction_map = {} @@ -1164,9 +1165,9 @@ class CodeBuilder(object): self.fence() self._add_inst_to_context(Raise(error_condition, error_message)) - def state_transition(self, next_state): + def phase_transition(self, next_phase): self.fence() - self._add_inst_to_context(StateTransition(next_state)) + self._add_inst_to_context(PhaseTransition(next_phase)) def __enter__(self): self._contexts.append(CodeBuilder.Context()) @@ -1174,7 +1175,7 @@ class CodeBuilder(object): def __exit__(self, *ignored): self.fence() - self.state_dependencies = list(self._contexts[-1].lead_instruction_ids) + self.phase_dependencies = list(self._contexts[-1].lead_instruction_ids) self.instructions = set(self._instruction_map.values()) def __str__(self): @@ -1185,13 +1186,13 @@ class CodeBuilder(object): return "\n".join(_stringify_instructions(roots, self._instruction_map)) - def as_execution_state(self, next_state): + def as_execution_phase(self, next_phase): """ :arg cb: A :class:`CodeBuilder` instance - :arg next_state: The name of the default next state + :arg next_phase: The name of the default next phase """ - return ExecutionState( - depends_on=self.state_dependencies, next_state=next_state, + return ExecutionPhase( + depends_on=self.phase_dependencies, next_phase=next_phase, instructions=self.instructions) # }}} @@ -1207,16 +1208,16 @@ def get_dot_dependency_graph(code, use_insn_ids=False): from pymbolic.imperative.utils import get_dot_dependency_graph def addtional_lines_hook(): - for i, (name, state) in enumerate(six.iteritems(code.states)): + for i, (name, phase) in enumerate(six.iteritems(code.phases)): yield "subgraph cluster_%d { label=\"%s\"" % (i, name) - for dep in state.depends_on: + for dep in phase.depends_on: yield dep yield "}" instructions = [ insn if use_insn_ids else insn.copy(id=insn.id) - for state_name, state in six.iteritems(code.states) - for insn in state.instructions] + for phase_name, phase in six.iteritems(code.phases) + for insn in phase.instructions] return get_dot_dependency_graph( instructions, use_insn_ids=use_insn_ids, addtional_lines_hook=addtional_lines_hook) diff --git a/dagrt/transform.py b/dagrt/transform.py index 5196813..cfbfb26 100644 --- a/dagrt/transform.py +++ b/dagrt/transform.py @@ -26,19 +26,19 @@ THE SOFTWARE. # {{{ insert_empty_intermediate_state def insert_empty_intermediate_state(dag, state_name, after_state): - new_states = dag.states.copy() + new_states = dag.phases.copy() if state_name in new_states: raise ValueError("state '%s' already exists" % state_name) - from dagrt.language import DAGCode, ExecutionState - new_states[state_name] = ExecutionState( - next_state=new_states[after_state].next_state) + from dagrt.language import DAGCode, ExecutionPhase + new_states[state_name] = ExecutionPhase( + next_phase=new_states[after_state].next_phase) new_states[after_state] = new_states[after_state].copy( - next_state=state_name) + next_phase=state_name) - return DAGCode(dag.instructions, new_states, dag.initial_state) + return DAGCode(dag.instructions, new_states, dag.initial_phase) # }}} @@ -46,9 +46,9 @@ def insert_empty_intermediate_state(dag, state_name, after_state): # {{{ fuse_two_states def fuse_two_states(state_name, state1, state2): - from dagrt.language import ExecutionState + from dagrt.language import ExecutionPhase if state1 is not None and state2 is not None: - if state1.next_state != state2.next_state: + if state1.next_phase != state2.next_phase: raise ValueError("DAGs don't agree on default " "state transition out of state '%s'" % state_name) @@ -57,8 +57,8 @@ def fuse_two_states(state_name, state1, state2): new_instructions, _, old_2_id_to_new_2_id = disambiguate_and_fuse( state1.instructions, state2.instructions) - return ExecutionState( - next_state=state1.next_state, + return ExecutionPhase( + next_phase=state1.next_phase, depends_on=frozenset(state1.depends_on) | frozenset( old_2_id_to_new_2_id.get(id2, id2) for id2 in state2.depends_on), @@ -81,16 +81,16 @@ def fuse_two_dags(dag1, dag2, state_correspondences=None, should_disambiguate_name=None): from dagrt.language import DAGCode new_states = {} - for state_name in frozenset(dag1.states) | frozenset(dag2.states): - state1 = dag1.states.get(state_name) - state2 = dag2.states.get(state_name) + for state_name in frozenset(dag1.phases) | frozenset(dag2.phases): + state1 = dag1.phases.get(state_name) + state2 = dag2.phases.get(state_name) new_states[state_name] = fuse_two_states(state_name, state1, state2) - if dag1.initial_state != dag2.initial_state: + if dag1.initial_phase != dag2.initial_phase: raise ValueError("DAGs don't agree on initial state") - return DAGCode(new_states, dag1.initial_state) + return DAGCode(new_states, dag1.initial_phase) # }}} diff --git a/examples/adaptive_rk.py b/examples/adaptive_rk.py index 8cc58b8..950d4c1 100644 --- a/examples/adaptive_rk.py +++ b/examples/adaptive_rk.py @@ -78,7 +78,7 @@ def adaptive_rk_method(tol): cb(y, y_h) cb(t, t + dt_old) - return DAGCode.create_with_steady_state(cb.state_dependencies, + return DAGCode.create_with_steady_phase(cb.phase_dependencies, cb.instructions) if __name__ == "__main__": diff --git a/test/test_ast.py b/test/test_ast.py index d161e2c..1cd726a 100755 --- a/test/test_ast.py +++ b/test/test_ast.py @@ -28,7 +28,7 @@ from pymbolic import var from pymbolic.primitives import LogicalNot from dagrt.codegen.ast import (IfThen, IfThenElse, Block, InstructionWrapper, - create_ast_from_state, simplify_ast) + create_ast_from_phase, simplify_ast) from dagrt.language import Instruction, DAGCode import pytest @@ -58,8 +58,8 @@ def test_create_ast(): return hash(self._state()) nop = ComparableNop(condition=x, id="nop", depends_on=()) - code = DAGCode.create_with_steady_state(["nop"], [nop]) - ast = create_ast_from_state(code, "main") + code = DAGCode.create_with_steady_phase(["nop"], [nop]) + ast = create_ast_from_phase(code, "main") assert ast == IfThen(x, InstructionWrapper(nop.copy(condition=True))) diff --git a/test/test_builtins.py b/test/test_builtins.py index 23f5a49..60c92c9 100755 --- a/test/test_builtins.py +++ b/test/test_builtins.py @@ -51,7 +51,7 @@ def test_len(python_method_impl, obj, len_): expression=var('x'), component_id='', depends_on=['assign_1'])) cbuild.commit() - code = DAGCode.create_with_steady_state( + code = DAGCode.create_with_steady_phase( dep_on=['return'], instructions=cbuild.instructions) @@ -69,7 +69,7 @@ def test_isnan(python_method_impl, value): expression=var('x'), component_id='', depends_on=['assign_1'])) cbuild.commit() - code = DAGCode.create_with_steady_state( + code = DAGCode.create_with_steady_phase( dep_on=['return'], instructions=cbuild.instructions) @@ -102,7 +102,7 @@ def test_norm(python_method_impl, order, norm_suffix, test_vector): expression=var('n'), component_id='', depends_on=['assign_2'])) cbuild.commit() - code = DAGCode.create_with_steady_state( + code = DAGCode.create_with_steady_phase( dep_on=['return'], instructions=cbuild.instructions) @@ -121,7 +121,7 @@ def test_dot_product(python_method_impl, x, y): expression=var('x'), component_id='', depends_on=['assign_1'])) cbuild.commit() - code = DAGCode.create_with_steady_state( + code = DAGCode.create_with_steady_phase( dep_on=['return'], instructions=cbuild.instructions) diff --git a/test/test_code_builder.py b/test/test_code_builder.py index 3f66c45..b93f826 100755 --- a/test/test_code_builder.py +++ b/test/test_code_builder.py @@ -41,8 +41,8 @@ THE SOFTWARE. def test_CodeBuilder_yield(python_method_impl): with CodeBuilder() as builder: builder.yield_state(1, 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 1 @@ -51,8 +51,8 @@ def test_CodeBuilder_assign(python_method_impl): with CodeBuilder() as builder: builder(var('x'), 1) builder.yield_state(var('x'), 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 1 @@ -63,8 +63,8 @@ def test_CodeBuilder_condition(python_method_impl): with builder.if_(var('x'), '==', 1): builder(var('x'), 2) builder.yield_state(var('x'), 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 2 @@ -77,8 +77,8 @@ def test_CodeBuilder_condition_with_else(python_method_impl): with builder.else_(): builder(var('x'), 3) builder.yield_state(var('x'), 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 3 @@ -91,8 +91,8 @@ def test_CodeBuilder_condition_with_else_not_taken(python_method_impl): with builder.else_(): builder(var('x'), 3) builder.yield_state(var('x'), 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 2 @@ -105,8 +105,8 @@ def test_CodeBuilder_nested_condition(python_method_impl): with builder.if_(var('x'), '==', 2): builder(var('x'), 3) builder.yield_state(var('x'), 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 3 @@ -121,8 +121,8 @@ def test_CodeBuilder_nested_condition_with_else(python_method_impl): with builder.else_(): builder(var('x'), 4) builder.yield_state(var('x'), 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 4 @@ -137,8 +137,8 @@ def test_CodeBuilder_nested_condition_with_else_not_taken(python_method_impl): with builder.else_(): builder(var('x'), 4) builder.yield_state(var('x'), 'x', 0, 'final') - code = DAGCode.create_with_steady_state( - builder.state_dependencies, builder.instructions) + code = DAGCode.create_with_steady_phase( + builder.phase_dependencies, builder.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 3 @@ -154,8 +154,8 @@ def test_CodeBuilder_exit_step(python_method_impl): builder2.yield_state(var('

x'), 'x', 0, 'final') code = DAGCode({ - "state1": builder1.as_execution_state("state2"), - "state2": builder2.as_execution_state("state2") + "state1": builder1.as_execution_phase("state2"), + "state2": builder2.as_execution_phase("state2") }, "state1") result = execute_and_return_single_result(python_method_impl, code) diff --git a/test/test_codegen.py b/test/test_codegen.py index cae360f..370a9e0 100755 --- a/test/test_codegen.py +++ b/test/test_codegen.py @@ -86,10 +86,10 @@ def test_missing_state_detection(): from dagrt.language import CodeBuilder with CodeBuilder(label="state_1") as cb: - cb.state_transition("state_2") + cb.phase_transition("state_2") - code = DAGCode.create_with_steady_state( - dep_on=cb.state_dependencies, instructions=cb.instructions) + code = DAGCode.create_with_steady_phase( + dep_on=cb.phase_dependencies, instructions=cb.instructions) with pytest.raises(CodeGenerationError): verify_code(code) diff --git a/test/test_codegen_fortran.py b/test/test_codegen_fortran.py index 9bc7f5d..e5b6cb3 100755 --- a/test/test_codegen_fortran.py +++ b/test/test_codegen_fortran.py @@ -99,8 +99,8 @@ def test_arrays_and_linalg(): with cb.if_("`norm_2`(myzero) > 10**(-8)"): cb.raise_(MatrixInversionFailure) - code = DAGCode.create_with_steady_state( - cb.state_dependencies, cb.instructions) + code = DAGCode.create_with_steady_phase( + cb.phase_dependencies, cb.instructions) codegen = f.CodeGenerator( 'arrays', diff --git a/test/test_codegen_python.py b/test/test_codegen_python.py index 3a127d7..b85c02c 100755 --- a/test/test_codegen_python.py +++ b/test/test_codegen_python.py @@ -59,11 +59,11 @@ def test_basic_codegen(): hist = [s for s in method.run(max_steps=2)] assert len(hist) == 3 assert isinstance(hist[0], method.StepCompleted) - assert hist[0].current_state == 'initialization' + assert hist[0].current_phase == 'initialization' assert isinstance(hist[1], method.StateComputed) assert hist[1].state_component == 0 assert isinstance(hist[2], method.StepCompleted) - assert hist[2].current_state == 'primary' + assert hist[2].current_phase == 'primary' def test_basic_conditional_codegen(): @@ -264,25 +264,25 @@ def test_function_name_distinctness(): assert hist[1].state_component == 1 -def test_state_transitions(python_method_impl): - from dagrt.language import CodeBuilder, ExecutionState +def test_phase_transitions(python_method_impl): + from dagrt.language import CodeBuilder, ExecutionPhase with CodeBuilder(label="state_1") as builder_1: builder_1(var("x"), 1) - builder_1.state_transition("state_2") + builder_1.phase_transition("state_2") with CodeBuilder(label="state_2") as builder_2: builder_2.yield_state(var("x"), 'x', 0, 'final') code = DAGCode( - states={ - "state_1": ExecutionState( - builder_1.state_dependencies, next_state="state_1", + phases={ + "state_1": ExecutionPhase( + builder_1.phase_dependencies, next_phase="state_1", instructions=builder_1.instructions), - "state_2": ExecutionState( - builder_2.state_dependencies, next_state="state_2", + "state_2": ExecutionPhase( + builder_2.phase_dependencies, next_phase="state_2", instructions=builder_2.instructions) }, - initial_state="state_1") + initial_phase="state_1") from utils import execute_and_return_single_result result = execute_and_return_single_result(python_method_impl, code, initial_context={'x': 0}, @@ -307,8 +307,8 @@ def get_IfThenElse_test_code_and_expected_result(): cb.yield_state(tuple(var("c" + str(i)) for i in range(1, 11)), "result", 0, "final") - code = DAGCode.create_with_steady_state( - cb.state_dependencies, cb.instructions) + code = DAGCode.create_with_steady_phase( + cb.phase_dependencies, cb.instructions) return (code, (0, 1, 0, 1, 0, 1, 1, 2, 1, 2)) @@ -338,8 +338,8 @@ def test_arrays_and_looping(python_method_impl): from utils import execute_and_return_single_result - code = DAGCode.create_with_steady_state( - cb.state_dependencies, cb.instructions) + code = DAGCode.create_with_steady_phase( + cb.phase_dependencies, cb.instructions) result = execute_and_return_single_result(python_method_impl, code) assert result == 15 @@ -374,8 +374,8 @@ def test_arrays_and_linalg(python_method_impl): from utils import execute_and_return_single_result - code = DAGCode.create_with_steady_state( - cb.state_dependencies, cb.instructions) + code = DAGCode.create_with_steady_phase( + cb.phase_dependencies, cb.instructions) result = execute_and_return_single_result(python_method_impl, code) result = result.reshape(4, 4, order="F") @@ -417,8 +417,8 @@ def test_svd(python_method_impl): from utils import execute_and_return_single_result - code = DAGCode.create_with_steady_state( - cb.state_dependencies, cb.instructions) + code = DAGCode.create_with_steady_phase( + cb.phase_dependencies, cb.instructions) result = execute_and_return_single_result(python_method_impl, code) assert la.norm(result) < 1e-10 -- GitLab From 93faba00b03a97eedd292d55545c1e61d8399366 Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Thu, 1 Mar 2018 19:56:03 -0600 Subject: [PATCH 2/5] Bump version --- dagrt/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dagrt/version.py b/dagrt/version.py index d26fbc2..aac0098 100644 --- a/dagrt/version.py +++ b/dagrt/version.py @@ -1,2 +1,2 @@ -VERSION = (2016, 1) +VERSION = (2018, 1) VERSION_TEXT = ".".join(str(i) for i in VERSION) -- GitLab From 98746a45506eb5e6efe149b66b423c1438c3a355 Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Thu, 1 Mar 2018 20:14:53 -0600 Subject: [PATCH 3/5] Fix dagrt.transform --- dagrt/transform.py | 66 +++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/dagrt/transform.py b/dagrt/transform.py index cfbfb26..3930521 100644 --- a/dagrt/transform.py +++ b/dagrt/transform.py @@ -25,72 +25,72 @@ THE SOFTWARE. # {{{ insert_empty_intermediate_state -def insert_empty_intermediate_state(dag, state_name, after_state): - new_states = dag.phases.copy() +def insert_empty_intermediate_state(dag, phase_name, after_phase): + new_phases = dag.phases.copy() - if state_name in new_states: - raise ValueError("state '%s' already exists" - % state_name) + if phase_name in new_phases: + raise ValueError("phase '%s' already exists" + % phase_name) from dagrt.language import DAGCode, ExecutionPhase - new_states[state_name] = ExecutionPhase( - next_phase=new_states[after_state].next_phase) - new_states[after_state] = new_states[after_state].copy( - next_phase=state_name) + new_phases[phase_name] = ExecutionPhase( + next_phase=new_phases[after_phase].next_phase) + new_phases[after_phase] = new_phases[after_phase].copy( + next_phase=phase_name) - return DAGCode(dag.instructions, new_states, dag.initial_phase) + return DAGCode(dag.instructions, new_phases, dag.initial_phase) # }}} -# {{{ fuse_two_states +# {{{ fuse_two_phases -def fuse_two_states(state_name, state1, state2): +def fuse_two_phases(phase_name, phase1, phase2): from dagrt.language import ExecutionPhase - if state1 is not None and state2 is not None: - if state1.next_phase != state2.next_phase: + if phase1 is not None and phase2 is not None: + if phase1.next_phase != phase2.next_phase: raise ValueError("DAGs don't agree on default " - "state transition out of state '%s'" - % state_name) + "phase transition out of phase '%s'" + % phase_name) from pymbolic.imperative.transform import disambiguate_and_fuse new_instructions, _, old_2_id_to_new_2_id = disambiguate_and_fuse( - state1.instructions, state2.instructions) + phase1.instructions, phase2.instructions) return ExecutionPhase( - next_phase=state1.next_phase, - depends_on=frozenset(state1.depends_on) | frozenset( + 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 state2.depends_on), + for id2 in phase2.depends_on), instructions=new_instructions ) - elif state1 is not None: - return state1 - elif state2 is not None: - return state2 + elif phase1 is not None: + return phase1 + elif phase2 is not None: + return phase2 else: - raise ValueError("both states are None") + raise ValueError("both phases are None") # }}} # {{{ fuse_two_dags -def fuse_two_dags(dag1, dag2, state_correspondences=None, +def fuse_two_dags(dag1, dag2, phase_correspondences=None, should_disambiguate_name=None): from dagrt.language import DAGCode - new_states = {} - for state_name in frozenset(dag1.phases) | frozenset(dag2.phases): - state1 = dag1.phases.get(state_name) - state2 = dag2.phases.get(state_name) + new_phases = {} + for phase_name in frozenset(dag1.phases) | frozenset(dag2.phases): + phase1 = dag1.phases.get(phase_name) + phase2 = dag2.phases.get(phase_name) - new_states[state_name] = fuse_two_states(state_name, state1, state2) + new_phases[phase_name] = fuse_two_phases(phase_name, phase1, phase2) if dag1.initial_phase != dag2.initial_phase: - raise ValueError("DAGs don't agree on initial state") + raise ValueError("DAGs don't agree on initial phase") - return DAGCode(new_states, dag1.initial_phase) + return DAGCode(new_phases, dag1.initial_phase) # }}} -- GitLab From 0bf1ddbac62c596274f326050914f4391337ef3d Mon Sep 17 00:00:00 2001 From: Matt Wala Date: Thu, 1 Mar 2018 20:25:59 -0600 Subject: [PATCH 4/5] Fix Fortran codegen API --- dagrt/codegen/fortran.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dagrt/codegen/fortran.py b/dagrt/codegen/fortran.py index 2685456..75366b6 100644 --- a/dagrt/codegen/fortran.py +++ b/dagrt/codegen/fortran.py @@ -2253,7 +2253,7 @@ class CodeGenerator(StructuredCodeGenerator): def emit_inst_ExitStep(self, inst): self.emit("goto 999") - def emit_inst_StateTransition(self, inst): + def emit_inst_PhaseTransition(self, inst): self.emit( 'dagrt_state%dagrt_next_phase = ' + self.state_name_to_state_sym(inst.next_phase)) -- GitLab From 1116f4dddb36bc0c422d343927c6101ce9f0c9c0 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 1 Mar 2018 22:25:07 -0600 Subject: [PATCH 5/5] Perform remainder of state -> phase transition in Fortran codegen --- dagrt/codegen/fortran.py | 144 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/dagrt/codegen/fortran.py b/dagrt/codegen/fortran.py index 75366b6..ce839bd 100644 --- a/dagrt/codegen/fortran.py +++ b/dagrt/codegen/fortran.py @@ -842,15 +842,15 @@ class CodeGenerator(StructuredCodeGenerator): The following attributes are available and allowed for read access in *dagrt_state_type* while outside of *run*: - * *dagrt_state_STATE_count* - * *dagrt_state_STATE_failures* - * *dagrt_state_STATE_time* + * *dagrt_state_PHASE_count* + * *dagrt_state_PHASE_failures* + * *dagrt_state_PHASE_time* * *dagrt_func_FUNC_count* * *dagrt_func_FUNC_time* - In all of the above, upper case denotes a "metavariable"--e.g. *STATE* is - the name of a state, or *FUNC* is the name of a function. The name of a + In all of the above, upper case denotes a "metavariable"--e.g. *PHASE* is + the name of a phase, or *FUNC* is the name of a function. The name of a function will typically be ``something``, for which *FUNC* will be ``func_something``. As a result, the profile field counting the number of invocations of the function ``something`` will be named @@ -990,8 +990,8 @@ class CodeGenerator(StructuredCodeGenerator): return "dagrt_deinit_"+make_identifier_from_name(utype_id) @staticmethod - def state_name_to_state_sym(state_name): - return "dagrt_state_"+state_name + def phase_name_to_phase_sym(phase_name): + return "dagrt_phase_"+phase_name @staticmethod def component_name_to_component_sym(comp_name): @@ -1108,9 +1108,9 @@ class CodeGenerator(StructuredCodeGenerator): self.current_function = function_name self.emit_def_begin( - 'dagrt_state_func_' + function_name, + 'dagrt_phase_func_' + function_name, self.extra_arguments + ('dagrt_state',), - state_id=function_name) + phase_id=function_name) self.declaration_emitter('type(dagrt_state_type), pointer :: dagrt_state') self.declaration_emitter('') @@ -1118,9 +1118,9 @@ class CodeGenerator(StructuredCodeGenerator): if self.emit_instrumentation: self.emit( - "dagrt_state%dagrt_state_{state}_count " - "= dagrt_state%dagrt_state_{state}_count + 1" - .format(state=function_name)) + "dagrt_state%dagrt_phase_{phase}_count " + "= dagrt_state%dagrt_phase_{phase}_count + 1" + .format(phase=function_name)) timer_start_var = self.name_manager.make_unique_fortran_name( "timer_start") @@ -1154,11 +1154,11 @@ class CodeGenerator(StructuredCodeGenerator): if self.emit_instrumentation: self.emit( - "dagrt_state%dagrt_state_{state}_time " - "= dagrt_state%dagrt_state_{state}_time " + "dagrt_state%dagrt_phase_{phase}_time " + "= dagrt_state%dagrt_phase_{phase}_time " "+ ({timing_function}() - {timer_start_var})" .format( - state=function_name, + phase=function_name, timing_function=self.timing_function, timer_start_var=timer_start_var, )) @@ -1211,14 +1211,14 @@ class CodeGenerator(StructuredCodeGenerator): time_id=time_id, i=i)) self.emit('') - # {{{ state name constants + # {{{ phase name constants - for i, state in enumerate(sorted(dag.phases)): - state_sym_name = self.state_name_to_state_sym(state) - self.emit("integer {state_sym_name}".format( - state_sym_name=state_sym_name)) - self.emit("parameter ({state_sym_name} = {i})".format( - state_sym_name=state_sym_name, i=i)) + for i, phase in enumerate(sorted(dag.phases)): + phase_sym_name = self.phase_name_to_phase_sym(phase) + self.emit("integer {phase_sym_name}".format( + phase_sym_name=phase_sym_name)) + self.emit("parameter ({phase_sym_name} = {i})".format( + phase_sym_name=phase_sym_name, i=i)) self.emit('') @@ -1265,10 +1265,10 @@ class CodeGenerator(StructuredCodeGenerator): emit('! {{{ instrumentation') emit('') - for state_name in sorted(dag.phases): - emit('integer dagrt_state_%s_count' % state_name) - emit('integer dagrt_state_%s_failures' % state_name) - emit('real*8 dagrt_state_%s_time' % state_name) + for phase_name in sorted(dag.phases): + emit('integer dagrt_phase_%s_count' % phase_name) + emit('integer dagrt_phase_%s_failures' % phase_name) + emit('real*8 dagrt_phase_%s_time' % phase_name) emit('') @@ -1614,18 +1614,18 @@ class CodeGenerator(StructuredCodeGenerator): for sym in init_symbols) function_name = 'initialize' - state_id = ""+function_name - self.emit_def_begin(function_name, args, state_id=state_id) + phase_id = ""+function_name + self.emit_def_begin(function_name, args, phase_id=phase_id) for sym in init_symbols: sym_kind = self.sym_kind_table.global_table[sym] fortran_name = self.name_manager.name_global(sym) - self.sym_kind_table.set(state_id, ""+fortran_name, sym_kind) + self.sym_kind_table.set(phase_id, ""+fortran_name, sym_kind) self.declaration_emitter('type(dagrt_state_type), pointer :: dagrt_state') self.declaration_emitter('') - self.current_function = state_id + self.current_function = phase_id for sym in init_symbols: sym_kind = self.sym_kind_table.global_table[sym] @@ -1644,7 +1644,7 @@ class CodeGenerator(StructuredCodeGenerator): self.emit("read(dagrt_nan_str,*) dagrt_nan") self.emit( - "dagrt_state%dagrt_next_phase = dagrt_state_{0}" + "dagrt_state%dagrt_next_phase = dagrt_phase_{0}" .format(dag.initial_phase)) for sym, sym_kind in sorted(six.iteritems( @@ -1707,10 +1707,10 @@ class CodeGenerator(StructuredCodeGenerator): self.emit('! {{{ instrumentation') self.emit('') - for state_name in sorted(dag.phases): - self.emit('dagrt_state%%dagrt_state_%s_count = 0' % state_name) - self.emit('dagrt_state%%dagrt_state_%s_failures = 0' % state_name) - self.emit('dagrt_state%%dagrt_state_%s_time = 0' % state_name) + for phase_name in sorted(dag.phases): + self.emit('dagrt_state%%dagrt_phase_%s_count = 0' % phase_name) + self.emit('dagrt_state%%dagrt_phase_%s_failures = 0' % phase_name) + self.emit('dagrt_state%%dagrt_phase_%s_time = 0' % phase_name) self.emit('') @@ -1737,13 +1737,13 @@ class CodeGenerator(StructuredCodeGenerator): args = self.extra_arguments + ('dagrt_state',) function_name = 'shutdown' - state_id = ""+function_name - self.emit_def_begin(function_name, args, state_id=state_id) + phase_id = ""+function_name + self.emit_def_begin(function_name, args, phase_id=phase_id) self.declaration_emitter('type(dagrt_state_type), pointer :: dagrt_state') self.declaration_emitter('') - self.current_function = state_id + self.current_function = phase_id from dagrt.codegen.data import UserType @@ -1775,18 +1775,18 @@ class CodeGenerator(StructuredCodeGenerator): args = self.extra_arguments + ('dagrt_state',) function_name = 'run' - state_id = ""+function_name - self.emit_def_begin(function_name, args, state_id=state_id) + phase_id = ""+function_name + self.emit_def_begin(function_name, args, phase_id=phase_id) self.declaration_emitter('type(dagrt_state_type), pointer :: dagrt_state') self.declaration_emitter('') - self.current_function = state_id + self.current_function = phase_id if_emit = None - for name, state_descr in sorted(six.iteritems(dag.phases)): - state_sym_name = self.state_name_to_state_sym(name) - cond = "dagrt_state%dagrt_next_phase == "+state_sym_name + for name, phase_descr in sorted(six.iteritems(dag.phases)): + phase_sym_name = self.phase_name_to_phase_sym(name) + cond = "dagrt_state%dagrt_next_phase == "+phase_sym_name if if_emit is None: if_emit = FortranIfEmitter( @@ -1797,16 +1797,16 @@ class CodeGenerator(StructuredCodeGenerator): self.emit( "dagrt_state%dagrt_next_phase = " - + self.state_name_to_state_sym(state_descr.next_phase)) + + self.phase_name_to_phase_sym(phase_descr.next_phase)) self.emit( - "call dagrt_state_func_{state_name}({args})".format( - state_name=name, + "call dagrt_phase_func_{phase_name}({args})".format( + phase_name=name, args=", ".join(args))) if if_emit: if_emit.emit_else() - self.emit("write(dagrt_stderr,*) 'encountered invalid state in run', " + self.emit("write(dagrt_stderr,*) 'encountered invalid phase in run', " "dagrt_state%dagrt_next_phase") self.emit("stop") @@ -1835,29 +1835,29 @@ class CodeGenerator(StructuredCodeGenerator): self.emit("write(*,*) 'dagrt profile information'") self.emit("write(*,*) '%s'" % delim) - for state_name in sorted(dag.phases): + for phase_name in sorted(dag.phases): self.emit( - "write(*,*) 'state {state} count:', " - "dagrt_state%dagrt_state_{state}_count" - .format(state=state_name)) + "write(*,*) 'phase {phase} count:', " + "dagrt_state%dagrt_phase_{phase}_count" + .format(phase=phase_name)) self.emit( - "write(*,*) 'state {state} failures:', " - "dagrt_state%dagrt_state_{state}_failures" - .format(state=state_name)) + "write(*,*) 'phase {phase} failures:', " + "dagrt_state%dagrt_phase_{phase}_failures" + .format(phase=phase_name)) with FortranIfEmitter( self.emitter, - 'dagrt_state%dagrt_state_{state}_count > 0' - .format(state=state_name), + 'dagrt_state%dagrt_phase_{phase}_count > 0' + .format(phase=phase_name), self): self.emit( - "write(*,*) 'state {state} mean time:', " - "dagrt_state%dagrt_state_{state}_time" - "/dagrt_state%dagrt_state_{state}_count" - .format(state=state_name)) + "write(*,*) 'phase {phase} mean time:', " + "dagrt_state%dagrt_phase_{phase}_time" + "/dagrt_state%dagrt_phase_{phase}_count" + .format(phase=phase_name)) self.emit( - "write(*,*) 'state {state} total time:', " - "dagrt_state%dagrt_state_{state}_time" - .format(state=state_name)) + "write(*,*) 'phase {phase} total time:', " + "dagrt_state%dagrt_phase_{phase}_time" + .format(phase=phase_name)) self.emit('') self.emit("write(*,*) '%s'" % delim) @@ -1979,7 +1979,7 @@ class CodeGenerator(StructuredCodeGenerator): # {{{ called by superclass - def emit_def_begin(self, function_name, argument_names, state_id=None, + def emit_def_begin(self, function_name, argument_names, phase_id=None, with_extra_args=True): self.declaration_emitter = FortranEmitter() @@ -1999,8 +1999,8 @@ class CodeGenerator(StructuredCodeGenerator): body_emitter = FortranEmitter() self.emitters.append(body_emitter) - if state_id is not None: - sym_table = self.sym_kind_table.per_function_table.get(state_id, {}) + if phase_id is not None: + sym_table = self.sym_kind_table.per_function_table.get(phase_id, {}) for identifier, sym_kind in sorted(six.iteritems(sym_table)): self.emit_variable_decl( self.name_manager[identifier], sym_kind, @@ -2013,7 +2013,7 @@ class CodeGenerator(StructuredCodeGenerator): self.emit_trace('================================================') self.emit_trace('enter %s' % function_name) - if state_id is not None: + if phase_id is not None: for identifier, sym_kind in sorted(six.iteritems(sym_table)): self.emit_variable_init(identifier, sym_kind) @@ -2244,9 +2244,9 @@ class CodeGenerator(StructuredCodeGenerator): def emit_inst_FailStep(self, inst): if self.emit_instrumentation: self.emit( - "dagrt_state%dagrt_state_{state}_failures " - "= dagrt_state%dagrt_state_{state}_failures + 1" - .format(state=self.current_function)) + "dagrt_state%dagrt_phase_{phase}_failures " + "= dagrt_state%dagrt_phase_{phase}_failures + 1" + .format(phase=self.current_function)) self.emit("goto 999") @@ -2256,7 +2256,7 @@ class CodeGenerator(StructuredCodeGenerator): def emit_inst_PhaseTransition(self, inst): self.emit( 'dagrt_state%dagrt_next_phase = ' - + self.state_name_to_state_sym(inst.next_phase)) + + self.phase_name_to_phase_sym(inst.next_phase)) # }}} -- GitLab