Reference

Description language

Identifier conventions

Identifiers whose names start with the pattern <letters> are special. The following special variable names are supported:

Internal names

<p>NAME
This variable contains persistent state. (that survives from one step to the next)
<cond>NAME
This variable is used by a conditional. May not be re-defined.
<dt>

The time increment for the present time step.

Its value at the beginning of a step indicates the step size to be used. If a time step of this size cannot be completed, FailStep must be issued.

This variable contains persistent state. (that survives from one step to the next)

<t>

Base time of current time step.

The integrator code is responsible for incrementing <t> at the end of a successful step.

This variable contains persistent state. (that survives from one step to the next)

User-controlled values

<state>NAME

State identifier under user (=scheme writer) control

This variable contains persistent state. (that survives from one step to the next)

<ret_time_id>COMPONENT_ID

<ret_time>COMPONENT_ID

<ret_state>COMPONENT_ID

For targets that are incapable of returning state mid-step, these variables are used to store computed state.

See 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_.

Statements

class dagrt.language.Statement(**kwargs)
Assignment Statements

These statements perform updates to the execution state, i.e. the variables.

class dagrt.language.AssignSolved(assignees, solve_variables, expressions, other_params, solver_id, **kwargs)
assignees

A tuple of strings. The names of the variables to assign with the results of solving for solve_variables

solve_variables

A tuple of strings, the names of the variables being solved for

expressions

A tuple of expressions, which represent the left hand sides of a system of (possibly nonlinear) equations. The solver will attempt to find a simultaneous root of the system.

other_params

A dictionary used to pass extra arguments to the solver, for instance a starting guess

solver_id

An identifier for the solver that is to be used to solve the system. This identifier is intended to match information about solvers which is supplied by the user.

class dagrt.language.AssignExpression(assignee=None, assignee_subscript=None, expression=None, loops=[], **kwargs)
loops

A list of triples (identifier, start, end) that the assignment should be carried out inside of these loops. No ordering of loop iterations is implied. The loops will typically be nested outer-to-inner, but a target may validly use any order it likes.

class dagrt.language.AssignFunctionCall(assignees, function_id, parameters, kw_parameters=None, **kwargs)

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 statement is justified by two facts:

  • Some backends (such as Fortran) choose to separate out function calls into individual statements. This statement provides a natural way to encode them.

    See leam.vm.codegen.transform.FunctionCallIsolator for a transform that accomplishes this.

  • Calling functions with multiple return values is not supported as part of dagrt’s language.

assignees

A tuple of variables to be passed assigned results from calling function_id.

function_id
parameters

A list of expressions to be passed as positional arguments.

kw_parameters

A dictionary mapping names to expressions to be passed as keyword arguments.

Control Statements

These statements affect the execution of a phase, or cause a phase to interact with user code.

class dagrt.language.YieldState(**kwargs)
time_id
time

A pymbolic expression representing the time at which the state returned is valid.

component_id
expression
class dagrt.language.Raise(error_condition, error_message=None, **kwargs)
error_condition

A (Python) exception type to be raised.

error_message

The error message to go along with that exception type.

class dagrt.language.FailStep(**kwargs)

Exits the current step with a failure indication to the controlling program. Execution resumes with the next step as normal.

class dagrt.language.ExitStep(**kwargs)

Exits the current step. Execution resumes with the next step as normal.

class dagrt.language.PhaseTransition(next_phase, **kwargs)
next_phase

The name of the next state to enter

Miscellaneous Statements
class dagrt.language.Nop(**kwargs)

Code Container

class dagrt.language.ExecutionPhase(depends_on, next_phase, statements)
depends_on

a list of statement IDs that need to be accomplished for successful execution of one round of this state

next_phase

name of the next state after this one, if no other state is specified by the user.

statements

is a list of Statement instances, in no particular order. Only statements referred to by depends_on or the transitive closure of their dependency relations will actually be executed.

class dagrt.language.DAGCode(phases, initial_phase)
phases

is a map from time integrator state names to ExecutionPhase instances

initial_phase

the name of the starting state

Visualization

dagrt.language.get_dot_dependency_graph(code, use_stmt_ids=False)

Return a string in the dot language depicting dependencies among kernel statements.

dagrt.language.show_dependency_graph(*args, **kwargs)

Show the dependency graph generated by get_dot_dependency_graph() in a browser. Accepts the same arguments as that function.

Code Creation

class dagrt.language.CodeBuilder(label='phase')
statements

The set of statements generated for the phase

phase_dependencies

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 statement.

fence()

Enter a new logical block of statements. Force all prior statements to execute before subsequent ones.

if_(*condition_arg)

Create a new block that is conditionally executed.

else_()

Create the “else” portion of a conditionally executed block.

__call__(assignees, expression, loops=[])

Generate code for an assignment.

assignees may be a variable, a subscript (if referring to an array), or a tuple of variables. There must be exactly one assignee unless expression is a function call.

fresh_var_name(prefix='temp')

Return a variable name that is not guaranteed not to be in use and not to be generated in the future.

fresh_var(prefix='temp')
assign_solved(assignees, solve_components, expressions, other_params, solver_id)
assign_solved_1(assignee, solve_component, expression, guess, solver_id=None)

Special case of AssignSolved when there is 1 component to solve for.

yield_state(expression, component_id, time, time_id)

Yield a value.

fail_step()
exit_step()
raise_(error_condition, error_message=None)
phase_transition(next_phase)
__enter__()
Parameters:label – The name of the phase to generate

Code generation

Python

Python code generator

class dagrt.codegen.python.CodeGenerator(class_name, function_registry=None)

Fortran

Fortran code generator

class dagrt.codegen.fortran.CodeGenerator(module_name, user_type_map, function_registry=None, module_preamble=None, real_scalar_kind='8', complex_scalar_kind='8', use_complex_scalars=True, call_before_state_update=None, call_after_state_update=None, extra_arguments=(), extra_argument_decl=None, parallel_do_preamble=None, emit_instrumentation=False, timing_function=None, trace=False)

Generates a Fortran module of name module_name, which defines a type dagrt_state_type to hold the current state of the time integrator along with several functions:

initialize(EXTRA_ARGUMENTS, dagrt_state, ...)
run(EXTRA_ARGUMENTS, dagrt_state)
shutdown(EXTRA_ARGUMENTS, dagrt_state)
print_profile(dagrt_state)

dagrt_state is of type dagrt_state_type`, and *EXTRA_ARGUMENTS above matches extra_arguments as passed to the constructor.

The ... arguments to initialize are optional and must be passed by keyword. The following keywords arguments are available:

  • dagrt_dt: The initial time step size
  • dagrt_t: The initial time
  • state_STATE: The initial value for the dagrt variable <state>STATE

Profiling information

The following attributes are available and allowed for read access in dagrt_state_type while outside of run:

  • 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. PHASE is the name of a phase, or FUNC is the name of a function. The name of a function will typically be <func>something, for which FUNC will be func_something. As a result, the profile field counting the number of invocations of the function <func>something will be named dagrt_func_func_something.

Parameters:
  • function_registry
  • user_type_map – a map from user type names to FortranType instances
  • call_before_state_update – The name of a function that should be called before each state update. The function must be known to function_registry.
  • call_after_state_update – The name of a function that should be called after each state update. The function must be known to function_registry.
  • extra_arguments – A tuple of names of extra arguments that are prepended to the call signature of each generated function and are available to refer to in user-supplied function implementations.
  • extra_argument_decl – Type declarations for extra_arguments, inserted into each generated function. Must be a multi-line string whose first line is empty, typically from a triple-quoted string in Python. Leading indentation is removed.
  • parallel_do_preambleNone or a string to be inserted before each constant-trip-count simd’able do loop.
  • emit_instrumentation – True or False, whether to emit performance instrumentation.
  • timing_functionNone or the name of a function that returns wall clock time as a number of seconds, as a real*8. Required if emit_instrumentation is set to True.

Function registry

The function registry is used by targets to register external functions and customized function call code.

class dagrt.function_registry.FixedResultKindsFunction(**kwargs)
get_result_kinds(arg_kinds, check)

Return a tuple of the dagrt.codegen.data.SymbolKind instances for the values this function returns if arguments of the kinds arg_kinds are supplied.

The length of the returned tuple must match the lenght of result_names.

Parameters:
  • arg_kinds – a dictionary mapping numbers (for positional arguments) or identifiers (for keyword arguments) to dagrt.codegen.data.SymbolKind instances indicating the types of the arguments being passed to the function. Some elements of arg_kinds may be None if their kinds have yet not been determined.
  • check – A bool. If True, none of arg_kinds will be None, and argument kind checking should be performed.
class dagrt.function_registry.Function(language_to_codegen=None, **kwargs)
result_names

A list of names of the return values of the function. Note that these names serve as documentation and as identifiers to be used for variables receiving function results inside generated code implementing the call to the function (e.g. in the Fortran backend). They have no relationship to the names to which the results ultimately get assigned.

identifier
arg_names
default_dict
get_result_kinds(arg_kinds, check)

Return a tuple of the dagrt.codegen.data.SymbolKind instances for the values this function returns if arguments of the kinds arg_kinds are supplied.

The length of the returned tuple must match the lenght of result_names.

Parameters:
  • arg_kinds – a dictionary mapping numbers (for positional arguments) or identifiers (for keyword arguments) to dagrt.codegen.data.SymbolKind instances indicating the types of the arguments being passed to the function. Some elements of arg_kinds may be None if their kinds have yet not been determined.
  • check – A bool. If True, none of arg_kinds will be None, and argument kind checking should be performed.
exception dagrt.function_registry.FunctionNotFound
class dagrt.function_registry.FunctionRegistry(id_to_function=None)
register(function)

Return a copy of self with function registered.

register_codegen(function_id, language, codegen)

Register a code generation helper object for target language for the function with identifier function_id.

Parameters:codegen – an object obeying an interface suitable for code generation for language. This interface depends on the code generator being used.

Transformations

Some generic DAG transformation passes

class dagrt.codegen.transform.FunctionArgumentIsolator(new_statements, stmt_id_gen, var_name_gen)
class dagrt.codegen.transform.FunctionCallIsolator(new_statements, stmt_id_gen, var_name_gen)
class dagrt.codegen.transform.IfThenElseExpander(new_statements, stmt_id_gen, var_name_gen)
dagrt.codegen.transform.expand_IfThenElse(dag)

Turn IfThenElse expressions into values that are computed as a result of an If statement. This is useful for targets that do not support ternary operators.

dagrt.codegen.transform.isolate_function_calls(dag)

isolate_function_arguments() should be called before this.

Utilities

Random usefulness

class dagrt.codegen.utils.KeyToUniqueNameMap(start={}, forced_prefix='', key_translate_func=<function make_identifier_from_name>, name_generator=None)

Maps keys to unique names that are created on-the-fly.

Before a unique name is created, a base name is first created. The base name consists of a forced prefix followed by a string that results from translating the key with a supplied function. The mapped value is then created from the base name.

dagrt.codegen.utils.remove_common_indentation(text)
Parameters:text – a multi-line string
Returns:a list of lines
dagrt.codegen.utils.wrap_line_base(line, level=0, width=80, indentation=' ', pad_func=<function <lambda>>, lex_func=functools.partial(<function split>, posix=False))

The input is a line of code at the given indentation level. Return the list of lines that results from wrapping the line to the given width. Lines subsequent to the first line in the returned list are padded with extra indentation. The initial indentation level is not included in the input or output lines.

The pad_func argument is a function that adds line continuations. The lex_func argument returns the list of tokens in the line.

Dumping ground of miscellaneous helpfulness.

exception dagrt.utils.TODO
class dagrt.utils.TemporaryDirectory(suffix='', prefix='tmp', dirname=None)

Create and return a temporary directory. This has the same behavior as mkdtemp but can be used as a context manager. For example:

with TemporaryDirectory() as tmpdir:

Upon exiting the context, the directory and everything contained in it are removed.

dagrt.utils.get_unique_name(prefix, *name_sets)

Return a name that begins with prefix and is not found in any of the name sets.

dagrt.utils.get_variables(expr, include_function_symbols=False)

Returns the set of names of variables used in the expression.

dagrt.utils.is_state_variable(var)

Check if the given name corresponds to a state variable.

dagrt.utils.resolve_args(arg_names, default_dict, arg_dict)

Resolve positional and keyword arguments to a single argument list.

Parameters:
  • arg_dict – a dictionary mapping numbers (for positional arguments) or identifiers (for keyword arguments) to values
  • default_dict – a dictionary mapping argument names to default values
  • arg_names – names of the positional arguments

numpy-based interpretation

exception dagrt.exec_numpy.ExitStepException
exception dagrt.exec_numpy.FailStepException
class dagrt.exec_numpy.NumpyInterpreter(code, function_map)

A numpy-targeting interpreter for the time integration language defined in dagrt.language.

next_phase
set_up(t_start, dt_start, context)
Parameters:context – a dictionary mapping identifiers to their values
run(t_end=None, max_steps=None)

Generates events.

run_single_step()
Parameters:
  • code – an instance of dagrt.DAGCode
  • function_map – a mapping from function identifiers to functions
class StateComputed
t
time_id
component_id

Identifier of the state component being returned.

state_component

Create new instance of StateComputed(t, time_id, component_id, state_component)

class StepCompleted
dt

Size of next time step.

t

Approximate integrator time at end of step.

current_state
next_phase

Create new instance of StepCompleted(dt, t, current_state, next_phase)

class StepFailed
t

Floating point number.

Create new instance of StepFailed(t,)

run(t_end=None, max_steps=None)

Generates events.

set_up(t_start, dt_start, context)
Parameters:context – a dictionary mapping identifiers to their values
class dagrt.exec_numpy.StateComputed
t
time_id
component_id

Identifier of the state component being returned.

state_component

Create new instance of StateComputed(t, time_id, component_id, state_component)

class dagrt.exec_numpy.StepCompleted
dt

Size of next time step.

t

Approximate integrator time at end of step.

current_state
next_phase

Create new instance of StepCompleted(dt, t, current_state, next_phase)

class dagrt.exec_numpy.StepFailed
t

Floating point number.

Create new instance of StepFailed(t,)

exception dagrt.exec_numpy.TransitionEvent(next_phase)