dace.sdfg package

Submodules

dace.sdfg.propagation module

Functionality relating to Memlet propagation (deducing external memlets from internal memory accesses and scope ranges).

class dace.sdfg.propagation.AffineSMemlet

Bases: dace.sdfg.propagation.SeparableMemletPattern

Separable memlet pattern that matches affine expressions, i.e., of the form a * {index} + b.

can_be_applied(dim_exprs, variable_context, node_range, orig_edges, dim_index, total_dims)
propagate(array, dim_exprs, node_range)
class dace.sdfg.propagation.ConstantRangeMemlet

Bases: dace.sdfg.propagation.MemletPattern

Memlet pattern that matches arbitrary expressions with constant range.

can_be_applied(expressions, variable_context, node_range, orig_edges)
propagate(array, expressions, node_range)
class dace.sdfg.propagation.ConstantSMemlet

Bases: dace.sdfg.propagation.SeparableMemletPattern

Separable memlet pattern that matches constant (i.e., unrelated to current scope) expressions.

can_be_applied(dim_exprs, variable_context, node_range, orig_edges, dim_index, total_dims)
propagate(array, dim_exprs, node_range)
class dace.sdfg.propagation.GenericSMemlet

Bases: dace.sdfg.propagation.SeparableMemletPattern

Separable memlet pattern that detects any expression, and propagates interval bounds. Used as a last resort.

can_be_applied(dim_exprs, variable_context, node_range, orig_edges, dim_index, total_dims)
propagate(array, dim_exprs, node_range)
class dace.sdfg.propagation.MemletPattern

Bases: object

A pattern match on a memlet subset that can be used for propagation.

can_be_applied(expressions, variable_context, node_range, orig_edges)
extensions()
propagate(array, expressions, node_range)
register(**kwargs)
unregister()
class dace.sdfg.propagation.ModuloSMemlet

Bases: dace.sdfg.propagation.SeparableMemletPattern

Separable memlet pattern that matches modulo expressions, i.e., of the form f(x) % N.

Acts as a meta-pattern: Finds the underlying pattern for f(x).

can_be_applied(dim_exprs, variable_context, node_range, orig_edges, dim_index, total_dims)
propagate(array, dim_exprs, node_range)
class dace.sdfg.propagation.SeparableMemlet

Bases: dace.sdfg.propagation.MemletPattern

Meta-memlet pattern that applies all separable memlet patterns.

can_be_applied(expressions, variable_context, node_range, orig_edges)
propagate(array, expressions, node_range)
class dace.sdfg.propagation.SeparableMemletPattern

Bases: object

Memlet pattern that can be applied to each of the dimensions separately.

can_be_applied(dim_exprs, variable_context, node_range, orig_edges, dim_index, total_dims)
extensions()
propagate(array, dim_exprs, node_range)
register(**kwargs)
unregister()
dace.sdfg.propagation.propagate_memlet(dfg_state, memlet: dace.memlet.Memlet, scope_node: dace.sdfg.nodes.EntryNode, union_inner_edges: bool, arr=None, connector=None)

Tries to propagate a memlet through a scope (computes the image of the memlet function applied on an integer set of, e.g., a map range) and returns a new memlet object. :param dfg_state: An SDFGState object representing the graph. :param memlet: The memlet adjacent to the scope node from the inside. :param scope_node: A scope entry or exit node. :param union_inner_edges: True if the propagation should take other

neighboring internal memlets within the same scope into account.
dace.sdfg.propagation.propagate_memlets_nested_sdfg(parent_sdfg, parent_state, nsdfg_node)

Propagate memlets out of a nested sdfg.

Parameters:
  • parent_sdfg – The parent SDFG this nested SDFG is in.
  • parent_state – The state containing this nested SDFG.
  • nsdfg_node – The NSDFG node containing this nested SDFG.
Note:

This operates in-place on the parent SDFG.

dace.sdfg.propagation.propagate_memlets_scope(sdfg, state, scopes)

Propagate memlets from the given scopes outwards. :param sdfg: The SDFG in which the scopes reside. :param state: The SDFG state in which the scopes reside. :param scopes: The ScopeTree object or a list thereof to start from. :note: This operation is performed in-place on the given SDFG.

dace.sdfg.propagation.propagate_memlets_sdfg(sdfg)

Propagates memlets throughout an entire given SDFG. :note: This is an in-place operation on the SDFG.

dace.sdfg.propagation.propagate_memlets_state(sdfg, state)

Propagates memlets throughout one SDFG state. :param sdfg: The SDFG in which the state is situated. :param state: The state to propagate in. :note: This is an in-place operation on the SDFG state.

dace.sdfg.propagation.propagate_states(sdfg) → None

Annotate the states of an SDFG with the number of executions.

Algorithm: 1. Clean up the state machine by splitting condition and assignment edges

into separate edes with a dummy state in between.
  1. Detect and annotate any for-loop constructs with their corresponding loop variable ranges.

  2. Start traversing the state machine from the start state (start state gets executed once by default). At every state, check the following:

    1. The state was already visited -> in this case it can either be the guard of a loop we’re returning to - in which case the number of executions is additively combined - or it is a state that can be reached through multiple paths (e.g. if/else branches), in which case the number of executions is equal to the maximum number of executions for each incoming path (in case this fully merges a previously branched out tree again, the number of executions isn’t dynamic anymore). In both cases we override the calculated number of executions if we’re propagating dynamic unbounded. This DFS traversal is complete and we continue with the next unvisited state.
    2. We’re propagating dynamic unbounded -> this overrides every calculated number of executions, so this gets unconditionally propagated to all child states.
    3. None of the above, the next regular traversal step is executed:
      3.1: If there is no further outgoing edge, this DFS traversal is
      done and we continue with the next unvisited state.
      3.2: If there is one outgoing edge, we continue propagating the
      same number of executions to the child state. If the transition to the child state is conditional, the current state might be an implicit exit state, in which case we mark the next state as dynamic to signal that it’s an upper bound.
      3.3: If there is more than one outgoing edge we:
      3.3.1: Check if it’s an annotated loop guard with a range. If
      so, we calculate the number of executions for the loop and propagate this down the loop.
      3.3.2: Check if it’s a loop that hasn’t been unannotated, which
      means it’s unbounded. In this case we propagate dynamic unbounded down the loop.
      3.3.3: Otherwise this must be a conditional branch, so this
      state’s number of executions is given to all child states as an upper bound.
  3. The traversal ends when all reachable states have been visited at least once.

Parameters:sdfg – The SDFG to annotate.
Note:This operates on the SDFG in-place.
dace.sdfg.propagation.propagate_subset(memlets: List[dace.memlet.Memlet], arr: dace.data.Data, params: List[str], rng: dace.subsets.Subset, defined_variables: Set[Union[sympy.core.basic.Basic, dace.symbolic.SymExpr]] = None, use_dst: bool = False) → dace.memlet.Memlet

Tries to propagate a list of memlets through a range (computes the image of the memlet function applied on an integer set of, e.g., a map range) and returns a new memlet object. :param memlets: The memlets to propagate. :param arr: Array descriptor for memlet (used for obtaining extents). :param params: A list of variable names. :param rng: A subset with dimensionality len(params) that contains the

range to propagate with.
Parameters:
  • defined_variables – A set of symbols defined that will remain the same throughout propagation. If None, assumes that all symbols outside of params have been defined.
  • use_dst – Whether to propagate the memlets’ dst subset or use the src instead, depending on propagation direction.
Returns:

Memlet with propagated subset and volume.

dace.sdfg.scope module

class dace.sdfg.scope.ScopeSubgraphView(graph, subgraph_nodes, entry_node)

Bases: dace.sdfg.state.StateSubgraphView

An extension to SubgraphView that enables the creation of scope dictionaries in subgraphs and free symbols.

parent
top_level_transients()

Iterate over top-level transients of this subgraph.

class dace.sdfg.scope.ScopeTree(entrynode: dace.sdfg.nodes.EntryNode, exitnode: dace.sdfg.nodes.ExitNode)

Bases: object

A class defining a scope, its parent and children scopes, and scope entry/exit nodes.

dace.sdfg.scope.devicelevel_block_size(sdfg: dace.sdfg.SDFG, state: dace.sdfg.SDFGState, node: dace.sdfg.nodes.Node) → Tuple[dace.symbolic.SymExpr]

Returns the current thread-block size if the given node is enclosed in a GPU kernel, or None otherwise. :param sdfg: The SDFG in which the node resides. :param state: The SDFG state in which the node resides. :param node: The node in question :return: A tuple of sizes or None if the node is not in device-level

code.
dace.sdfg.scope.is_devicelevel_fpga(sdfg: dace.sdfg.SDFG, state: dace.sdfg.SDFGState, node: dace.sdfg.nodes.Node) → bool

Tests whether a node in an SDFG is contained within FPGA device-level code. :param sdfg: The SDFG in which the node resides. :param state: The SDFG state in which the node resides. :param node: The node in question :return: True if node is in device-level code, False otherwise.

dace.sdfg.scope.is_devicelevel_gpu(sdfg: dace.sdfg.SDFG, state: dace.sdfg.SDFGState, node: dace.sdfg.nodes.Node, with_gpu_default: bool = False) → bool

Tests whether a node in an SDFG is contained within GPU device-level code. :param sdfg: The SDFG in which the node resides. :param state: The SDFG state in which the node resides. :param node: The node in question :return: True if node is in device-level code, False otherwise.

dace.sdfg.scope.is_in_scope(sdfg: dace.sdfg.SDFG, state: dace.sdfg.SDFGState, node: dace.sdfg.nodes.Node, schedules: List[dace.dtypes.ScheduleType]) → bool

Tests whether a node in an SDFG is contained within a certain set of scope schedules. :param sdfg: The SDFG in which the node resides. :param state: The SDFG state in which the node resides. :param node: The node in question :return: True if node is in device-level code, False otherwise.

dace.sdfg.scope.scope_contains_scope(sdict: Dict[dace.sdfg.nodes.Node, List[dace.sdfg.nodes.Node]], node: dace.sdfg.nodes.Node, other_node: dace.sdfg.nodes.Node) → bool

Returns true iff scope of node contains the scope of other_node.

dace.sdfg.sdfg module

class dace.sdfg.sdfg.InterstateEdge(*args, **kwargs)

Bases: object

An SDFG state machine edge. These edges can contain a condition (which may include data accesses for data-dependent decisions) and zero or more assignments of values to inter-state variables (e.g., loop iterates).

assignments

Assignments to perform upon transition (e.g., ‘x=x+1; y = 0’)

condition

Transition condition

condition_sympy()
free_symbols

Returns a set of symbols used in this edge’s properties.

static from_json(json_obj, context=None)
is_unconditional()

Returns True if the state transition is unconditional.

label
new_symbols(symbols) → Dict[str, dace.dtypes.typeclass]

Returns a mapping between symbols defined by this edge (i.e., assignments) to their type.

properties()
replace(name: str, new_name: str, replace_keys=True) → None

Replaces all occurrences of name with new_name. :param name: The source name. :param new_name: The replacement name. :param replace_keys: If False, skips replacing assignment keys.

to_json(parent=None)
class dace.sdfg.sdfg.SDFG(*args, **kwargs)

Bases: dace.sdfg.graph.OrderedDiGraph

The main intermediate representation of code in DaCe.

A Stateful DataFlow multiGraph (SDFG) is a directed graph of directed acyclic multigraphs (i.e., where two nodes can be connected by more than one edge). The top-level directed graph represents a state machine, where edges can contain state transition conditions and assignments (see the InterstateEdge class documentation). The nested acyclic multigraphs represent dataflow, where nodes may represent data regions in memory, tasklets, or parametric graph scopes (see dace.sdfg.nodes for a full list of available node types); edges in the multigraph represent data movement using memlets, as described in the Memlet class documentation.

add_array(name: str, shape, dtype, storage=<StorageType.Default: 1>, transient=False, strides=None, offset=None, lifetime=<AllocationLifetime.Scope: 1>, debuginfo=None, allow_conflicts=False, total_size=None, find_new_name=False, alignment=0, may_alias=False) → Tuple[str, dace.data.Array]

Adds an array to the SDFG data descriptor store.

add_constant(name: str, value: Any, dtype: dace.data.Data = None)

Adds/updates a new compile-time constant to this SDFG. A constant may either be a scalar or a numpy ndarray thereof. :param name: The name of the constant. :param value: The constant value. :param dtype: Optional data type of the symbol, or None to deduce

automatically.
add_datadesc(name: str, datadesc: dace.data.Data, find_new_name=False) → str

Adds an existing data descriptor to the SDFG array store. :param name: Name to use. :param datadesc: Data descriptor to add. :param find_new_name: If True and data descriptor with this name

exists, finds a new name to add.
Returns:Name of the new data descriptor
add_edge(u, v, edge)

Adds a new edge to the SDFG. Must be an InterstateEdge or a subclass thereof. :param u: Source node. :param v: Destination node. :param edge: The edge to add.

add_loop(before_state, loop_state, after_state, loop_var: str, initialize_expr: str, condition_expr: str, increment_expr: str, loop_end_state=None)

Helper function that adds a looping state machine around a given state (or sequence of states). :param before_state: The state after which the loop should

begin, or None if the loop is the first state (creates an empty state).
Parameters:
  • loop_state – The state that begins the loop. See also loop_end_state if the loop is multi-state.
  • after_state – The state that should be invoked after the loop ends, or None if the program should terminate (creates an empty state).
  • loop_var – A name of an inter-state variable to use for the loop. If None, initialize_expr and increment_expr must be None.
  • initialize_expr – A string expression that is assigned to loop_var before the loop begins. If None, does not define an expression.
  • condition_expr – A string condition that occurs every loop iteration. If None, loops forever (undefined behavior).
  • increment_expr

    A string expression that is assigned to loop_var after every loop iteration.

    If None, does not define an expression.
  • loop_end_state – If the loop wraps multiple states, the state where the loop iteration ends. If None, sets the end state to loop_state as well.
Returns:

A 3-tuple of (before_state, generated loop guard state, after_state).

add_node(node, is_start_state=False)

Adds a new node to the SDFG. Must be an SDFGState or a subclass thereof. :param node: The node to add. :param is_start_state: If True, sets this node as the starting

state.
add_scalar(name: str, dtype, storage=<StorageType.Default: 1>, transient=False, lifetime=<AllocationLifetime.Scope: 1>, debuginfo=None, find_new_name=False) → Tuple[str, dace.data.Scalar]

Adds a scalar to the SDFG data descriptor store.

add_state(label=None, is_start_state=False) → dace.sdfg.state.SDFGState

Adds a new SDFG state to this graph and returns it. :param label: State label. :param is_start_state: If True, resets SDFG starting state to this

state.
Returns:A new SDFGState object.
add_state_after(state: dace.sdfg.state.SDFGState, label=None, is_start_state=False) → dace.sdfg.state.SDFGState

Adds a new SDFG state after an existing state, reconnecting it to the successors instead. :param state: The state to append the new state after. :param label: State label. :param is_start_state: If True, resets SDFG starting state to this

state.
Returns:A new SDFGState object.
add_state_before(state: dace.sdfg.state.SDFGState, label=None, is_start_state=False) → dace.sdfg.state.SDFGState

Adds a new SDFG state before an existing state, reconnecting predecessors to it instead. :param state: The state to prepend the new state before. :param label: State label. :param is_start_state: If True, resets SDFG starting state to this

state.
Returns:A new SDFGState object.
add_stream(name: str, dtype, buffer_size=1, shape=(1, ), storage=<StorageType.Default: 1>, transient=False, offset=None, lifetime=<AllocationLifetime.Scope: 1>, debuginfo=None, find_new_name=False) → Tuple[str, dace.data.Stream]

Adds a stream to the SDFG data descriptor store.

add_symbol(name, stype)

Adds a symbol to the SDFG. :param name: Symbol name. :param stype: Symbol type.

add_temp_transient(shape, dtype, storage=<StorageType.Default: 1>, strides=None, offset=None, lifetime=<AllocationLifetime.Scope: 1>, debuginfo=None, allow_conflicts=False, total_size=None, alignment=0, may_alias=False)

Convenience function to add a transient array with a temporary name to the data descriptor store.

add_transient(name, shape, dtype, storage=<StorageType.Default: 1>, strides=None, offset=None, lifetime=<AllocationLifetime.Scope: 1>, debuginfo=None, allow_conflicts=False, total_size=None, find_new_name=False, alignment=0, may_alias=False) → Tuple[str, dace.data.Array]

Convenience function to add a transient array to the data descriptor store.

add_view(name: str, shape, dtype, storage=<StorageType.Default: 1>, strides=None, offset=None, debuginfo=None, allow_conflicts=False, total_size=None, find_new_name=False, alignment=0, may_alias=False) → Tuple[str, dace.data.View]

Adds a view to the SDFG data descriptor store.

all_edges_recursive()

Iterate over all edges in this SDFG, including state edges, inter-state edges, and recursively edges within nested SDFGs, returning tuples on the form (edge, parent), where the parent is either the SDFG (for states) or a DFG (nodes).

all_nodes_recursive() → Iterator[Tuple[dace.sdfg.nodes.Node, Union[dace.sdfg.sdfg.SDFG, dace.sdfg.state.SDFGState]]]

Iterate over all nodes in this SDFG, including states, nodes in states, and recursive states and nodes within nested SDFGs, returning tuples on the form (node, parent), where the parent is either the SDFG (for states) or a DFG (nodes).

all_sdfgs_recursive()

Iterate over this and all nested SDFGs.

append_exit_code(cpp_code: str, location: str = 'frame')

Appends C++ code that will be generated in the __dace_exit_* functions on one of the generated code files. :param cpp_code: The code to append. :param location: The file/backend in which to generate the code.

Options are None (all files), “frame”, “openmp”, “cuda”, “xilinx”, “intel_fpga”, or any code generator name.
append_global_code(cpp_code: str, location: str = 'frame')

Appends C++ code that will be generated in a global scope on one of the generated code files. :param cpp_code: The code to set. :param location: The file/backend in which to generate the code.

Options are None (all files), “frame”, “openmp”, “cuda”, “xilinx”, “intel_fpga”, or any code generator name.
append_init_code(cpp_code: str, location: str = 'frame')

Appends C++ code that will be generated in the __dace_init_* functions on one of the generated code files. :param cpp_code: The code to append. :param location: The file/backend in which to generate the code.

Options are None (all files), “frame”, “openmp”, “cuda”, “xilinx”, “intel_fpga”, or any code generator name.
append_transformation(transformation)

Appends a transformation to the treansformation history of this SDFG. If this is the first transformation being applied, it also saves the initial state of the SDFG to return to and play back the history. :param transformation: The transformation to append.

apply_gpu_transformations(states=None, validate=True, validate_all=False, strict=True)

Applies a series of transformations on the SDFG for it to generate GPU code. :note: It is recommended to apply redundant array removal transformation after this transformation. Alternatively, you can apply_strict_transformations() after this transformation. :note: This is an in-place operation on the SDFG.

apply_strict_transformations(validate=True, validate_all=False)

Applies safe transformations (that will surely increase the performance) on the SDFG. For example, this fuses redundant states (safely) and removes redundant arrays.

B{Note:} This is an in-place operation on the SDFG.

apply_transformations(xforms: Union[Type[CT_co], List[Type[CT_co]]], options: Union[Dict[str, Any], List[Dict[str, Any]], None] = None, validate: bool = True, validate_all: bool = False, strict: bool = False, states: Optional[List[Any]] = None, print_report: Optional[bool] = None) → int

This function applies a transformation or a sequence thereof consecutively. Operates in-place. :param xforms: A Transformation class or a sequence. :param options: An optional dictionary (or sequence of dictionaries)

to modify transformation parameters.
Parameters:
  • validate – If True, validates after all transformations.
  • validate_all – If True, validates after every transformation.
  • strict – If True, operates in strict transformation mode.
  • states – If not None, specifies a subset of states to apply transformations on.
  • print_report – Whether to show debug prints or not (None if the DaCe config option ‘debugprint’ should apply)
Returns:

Number of transformations applied.

Examples:

# Applies MapTiling, then MapFusion, followed by
# GPUTransformSDFG, specifying parameters only for the
# first transformation.
sdfg.apply_transformations(
  [MapTiling, MapFusion, GPUTransformSDFG],
  options=[{'tile_size': 16}, {}, {}])
apply_transformations_repeated(xforms: Union[Type[CT_co], List[Type[CT_co]]], options: Union[Dict[str, Any], List[Dict[str, Any]], None] = None, validate: bool = True, validate_all: bool = False, strict: bool = False, states: Optional[List[Any]] = None, print_report: Optional[bool] = None, order_by_transformation: bool = True) → int

This function repeatedly applies a transformation or a set of (unique) transformations until none can be found. Operates in-place. :param xforms: A Transformation class or a set thereof. :param options: An optional dictionary (or sequence of dictionaries)

to modify transformation parameters.
Parameters:
  • validate – If True, validates after all transformations.
  • validate_all – If True, validates after every transformation.
  • strict – If True, operates in strict transformation mode.
  • states – If not None, specifies a subset of states to apply transformations on.
  • print_report – Whether to show debug prints or not (None if the DaCe config option ‘debugprint’ should apply).
  • order_by_transformation – Try to apply transformations ordered by class rather than SDFG.
Returns:

Number of transformations applied.

Examples:

# Applies InlineSDFG until no more subgraphs can be inlined
sdfg.apply_transformations_repeated(InlineSDFG)
arg_types

Formal parameter list

arglist(scalars_only=False) → Dict[str, dace.data.Data]

Returns an ordered dictionary of arguments (names and types) required to invoke this SDFG.

The arguments follow the following order: <sorted data arguments>, <sorted scalar arguments>. Data arguments are all the non-transient data containers in the SDFG; and scalar arguments are all the non-transient scalar data containers and free symbols (see SDFG.free_symbols). This structure will create a sorted list of pointers followed by a sorted list of PoDs and structs.

Returns:An ordered dictionary of (name, data descriptor type) of all the arguments, sorted as defined here.
argument_typecheck(args, kwargs, types_only=False)

Checks if arguments and keyword arguments match the SDFG types. Raises RuntimeError otherwise.

Raises:
  • RuntimeError – Argument count mismatch.
  • TypeError – Argument type mismatch.
  • NotImplementedError – Unsupported argument type.
arrays

Returns a dictionary of data descriptors (Data objects) used in this SDFG, with an extra None entry for empty memlets.

arrays_recursive()

Iterate over all arrays in this SDFG, including arrays within nested SDFGs. Yields 3-tuples of (sdfg, array name, array).

build_folder

Returns a relative path to the build cache folder for this SDFG.

clear_instrumentation_reports()

Clears the instrumentation report folder of this SDFG.

compile(output_file=None) → dace.codegen.compiler.CompiledSDFG

Compiles a runnable binary from this SDFG. :param output_file: If not None, copies the output library file to

the specified path.
Returns:A callable CompiledSDFG object.
constants

A dictionary of compile-time constants defined in this SDFG.

constants_prop

Compile-time constants

data(dataname: str)

Looks up a data descriptor from its name, which can be an array, stream, or scalar symbol.

exit_code

Code generated in the __dace_exit function.

expand_library_nodes(recursive=True)

Recursively expand all unexpanded library nodes in the SDFG, resulting in a “pure” SDFG that the code generator can handle. :param recursive: If True, expands all library nodes recursively,

including library nodes that expand to library nodes.
fill_scope_connectors()

Fills missing scope connectors (i.e., “IN_#”/”OUT_#” on entry/exit nodes) according to data on the memlets.

find_new_constant(name: str)

Tries to find a new constant name by adding an underscore and a number.

find_state(state_id_or_label)

Finds a state according to its ID (if integer is provided) or label (if string is provided).

Parameters:state_id_or_label – State ID (if int) or label (if str).
Returns:An SDFGState object.
free_symbols

Returns a set of symbol names that are used by the SDFG, but not defined within it. This property is used to determine the symbolic parameters of the SDFG and verify that SDFG.symbols is complete. :note: Assumes that the graph is valid (i.e., without undefined or

overlapping symbols).
static from_file(filename: str) → dace.sdfg.sdfg.SDFG

Constructs an SDFG from a file. :param filename: File name to load SDFG from. :return: An SDFG.

classmethod from_json(json_obj, context_info=None)
generate_code()

Generates code from this SDFG and returns it. :return: A list of CodeObject objects containing the generated

code of different files and languages.
get_instrumentation_reports() → List[dace.codegen.instrumentation.report.InstrumentationReport]

Returns a list of instrumentation reports from previous runs of this SDFG. :return: A List of timestamped InstrumentationReport objects.

get_latest_report() → Optional[dace.codegen.instrumentation.report.InstrumentationReport]

Returns an instrumentation report from the latest run of this SDFG, or None if the file does not exist. :return: A timestamped InstrumentationReport object, or None if does

not exist.
global_code

Code generated in a global scope on the output files.

hash_sdfg(jsondict: Optional[Dict[str, Any]] = None) → str

Returns a hash of the current SDFG, without considering IDs and attribute names. :param jsondict: If not None, uses given JSON dictionary as input. :return: The hash (in SHA-256 format).

init_code

Code generated in the __dace_init function.

input_arrays()

Returns a list of input arrays that need to be fed into the SDFG.

instrument

Measure execution statistics with given method

is_instrumented() → bool

Returns True if the SDFG has performance instrumentation enabled on it or any of its elements.

is_valid() → bool

Returns True if the SDFG is verified correctly (using validate).

label

The name of this SDFG.

make_array_memlet(array: str)

Convenience method to generate a Memlet that transfers a full array.

Parameters:array – the name of the array
Returns:a Memlet that fully transfers array
name

The name of this SDFG.

optimize(optimizer=None) → dace.sdfg.sdfg.SDFG

Optimize an SDFG using the CLI or external hooks. :param optimizer: If defines a valid class name, it will be called

during compilation to transform the SDFG as necessary. If None, uses configuration setting.
Returns:An SDFG (returns self if optimizer is in place)
orig_sdfg

Object property of type SDFGReferenceProperty

output_arrays()

Returns a list of output arrays that need to be returned from the SDFG.

parent

Returns the parent SDFG state of this SDFG, if exists.

parent_nsdfg_node

Returns the parent NestedSDFG node of this SDFG, if exists.

parent_sdfg

Returns the parent SDFG of this SDFG, if exists.

predecessor_state_transitions(state)

Yields paths (lists of edges) that the SDFG can pass through before computing the given state.

predecessor_states(state)

Returns a list of unique states that the SDFG can pass through before computing the given state.

prepend_exit_code(cpp_code: str, location: str = 'frame')

Prepends C++ code that will be generated in the __dace_exit_* functions on one of the generated code files. :param cpp_code: The code to prepend. :param location: The file/backend in which to generate the code.

Options are None (all files), “frame”, “openmp”, “cuda”, “xilinx”, “intel_fpga”, or any code generator name.
propagate
properties()
read_and_write_sets() → Tuple[Set[AnyStr], Set[AnyStr]]

Determines what data containers are read and written in this SDFG. Does not include reads to subsets of containers that have previously been written within the same state. :return: A two-tuple of sets of things denoting

({data read}, {data written}).
remove_data(name, validate=True)

Removes a data descriptor from the SDFG. :param name: The name of the data descriptor to remove. :param validate: If True, verifies that there are no access

nodes that are using this data descriptor prior to removing it.
remove_symbol(name)

Removes a symbol from the SDFG. :param name: Symbol name.

replace(name: str, new_name: str)

Finds and replaces all occurrences of a symbol or array name in SDFG. :param name: Name to find. :param new_name: Name to replace. :raise FileExistsError: If name and new_name already exist as data descriptors or symbols.

reset_sdfg_list()
save(filename: str, use_pickle=False, with_metadata=False, hash=None, exception=None) → Optional[str]

Save this SDFG to a file. :param filename: File name to save to. :param use_pickle: Use Python pickle as the SDFG format (default:

JSON).
Parameters:
  • with_metadata – Save property metadata (e.g. name, description). False or True override current option, whereas None keeps default.
  • hash – By default, saves the hash if SDFG is JSON-serialized. Otherwise, if True, saves the hash along with the SDFG.
  • exception – If not None, stores error information along with SDFG.
Returns:

The hash of the SDFG, or None if failed/not requested.

sdfg_id

Returns the unique index of the current SDFG within the current tree of SDFGs (top-level SDFG is 0, nested SDFGs are greater).

sdfg_list
set_exit_code(cpp_code: str, location: str = 'frame')

Sets C++ code that will be generated in the __dace_exit_* functions on one of the generated code files. :param cpp_code: The code to set. :param location: The file/backend in which to generate the code.

Options are None (all files), “frame”, “openmp”, “cuda”, “xilinx”, “intel_fpga”, or any code generator name.
set_global_code(cpp_code: str, location: str = 'frame')

Sets C++ code that will be generated in a global scope on one of the generated code files. :param cpp_code: The code to set. :param location: The file/backend in which to generate the code.

Options are None (all files), “frame”, “openmp”, “cuda”, “xilinx”, “intel_fpga”, or any code generator name.
set_init_code(cpp_code: str, location: str = 'frame')

Sets C++ code that will be generated in the __dace_init_* functions on one of the generated code files. :param cpp_code: The code to set. :param location: The file/backend in which to generate the code.

Options are None (all files), “frame”, “openmp”, “cuda”, “xilinx”, “intel_fpga”, or any code generator name.
set_sourcecode(code: str, lang=None)

Set the source code of this SDFG (for IDE purposes). :param code: A string of source code. :param lang: A string representing the language of the source code,

for syntax highlighting and completion.
shared_transients() → List[str]

Returns a list of transient data that appears in more than one state.

signature(with_types=True, for_call=False, with_arrays=True) → str

Returns a C/C++ signature of this SDFG, used when generating code. :param with_types: If True, includes argument types (can be used

for a function prototype). If False, only include argument names (can be used for function calls).
Parameters:
  • for_call – If True, returns arguments that can be used when calling the SDFG.
  • with_arrays – If True, includes arrays, otherwise, only symbols and scalars are included.
signature_arglist(with_types=True, for_call=False, with_arrays=True) → List[str]

Returns a list of arguments necessary to call this SDFG, formatted as a list of C definitions. :param with_types: If True, includes argument types in the result. :param for_call: If True, returns arguments that can be used when

calling the SDFG.
Parameters:with_arrays – If True, includes arrays, otherwise, only symbols and scalars are included.
Returns:A list of strings. For example: [‘float *A’, ‘int b’].
specialize(symbols: Dict[str, Any])

Sets symbolic values in this SDFG to constants. :param symbols: Values to specialize.

start_state

Returns the starting state of this SDFG.

states()

Alias that returns the nodes (states) in this SDFG.

symbols

Global symbols for this SDFG

temp_data_name()

Returns a temporary data descriptor name that can be used in this SDFG.

to_json(hash=False)

Serializes this object to JSON format. :return: A string representing the JSON-serialized SDFG.

transformation_hist

Object property of type list

transients()

Returns a dictionary mapping transient data descriptors to their parent scope entry node, or None if top-level (i.e., exists in multiple scopes).

update_sdfg_list(sdfg_list)
validate() → None
view(filename=None)

View this sdfg in the system’s HTML viewer :param filename: the filename to write the HTML to. If None, a temporary file will be created.

dace.sdfg.utils module

Various utility functions to create, traverse, and modify SDFGs.

dace.sdfg.utils.change_edge_dest(graph: dace.sdfg.graph.OrderedDiGraph, node_a: Union[dace.sdfg.nodes.Node, dace.sdfg.graph.OrderedMultiDiConnectorGraph], node_b: Union[dace.sdfg.nodes.Node, dace.sdfg.graph.OrderedMultiDiConnectorGraph])

Changes the destination of edges from node A to node B.

The function finds all edges in the graph that have node A as their destination. It then creates a new edge for each one found, using the same source nodes and data, but node B as the destination. Afterwards, it deletes the edges found and inserts the new ones into the graph.

Parameters:
  • graph – The graph upon which the edge transformations will be applied.
  • node_a – The original destination of the edges.
  • node_b – The new destination of the edges to be transformed.
dace.sdfg.utils.change_edge_src(graph: dace.sdfg.graph.OrderedDiGraph, node_a: Union[dace.sdfg.nodes.Node, dace.sdfg.graph.OrderedMultiDiConnectorGraph], node_b: Union[dace.sdfg.nodes.Node, dace.sdfg.graph.OrderedMultiDiConnectorGraph])

Changes the sources of edges from node A to node B.

The function finds all edges in the graph that have node A as their source. It then creates a new edge for each one found, using the same destination nodes and data, but node B as the source. Afterwards, it deletes the edges found and inserts the new ones into the graph.

Parameters:
  • graph – The graph upon which the edge transformations will be applied.
  • node_a – The original source of the edges to be transformed.
  • node_b – The new source of the edges to be transformed.
dace.sdfg.utils.concurrent_subgraphs(graph)

Finds subgraphs of an SDFGState or ScopeSubgraphView that can run concurrently.

dace.sdfg.utils.consolidate_edges(sdfg: dace.sdfg.sdfg.SDFG, starting_scope=None) → int

Union scope-entering memlets relating to the same data node in all states. This effectively reduces the number of connectors and allows more transformations to be performed, at the cost of losing the individual per-tasklet memlets. :param sdfg: The SDFG to consolidate. :return: Number of edges removed.

dace.sdfg.utils.consolidate_edges_scope(state: dace.sdfg.state.SDFGState, scope_node: Union[dace.sdfg.nodes.EntryNode, dace.sdfg.nodes.ExitNode]) → int

Union scope-entering memlets relating to the same data node in a scope. This effectively reduces the number of connectors and allows more transformations to be performed, at the cost of losing the individual per-tasklet memlets. :param state: The SDFG state in which the scope to consolidate resides. :param scope_node: The scope node whose edges will be consolidated. :return: Number of edges removed.

dace.sdfg.utils.depth_limited_dfs_iter(source, depth)

Produce nodes in a Depth-Limited DFS.

Return best node and its value using a limited-depth Search (depth- limited DFS).

dace.sdfg.utils.dfs_conditional(G, sources=None, condition=None)

Produce nodes in a depth-first ordering.

Parameters:
  • G – An input DiGraph (assumed acyclic).
  • sources – (optional) node or list of nodes that specify starting point(s) for depth-first search and return edges in the component reachable from source.
Returns:

A generator of edges in the lastvisit depth-first-search.

@note: Based on http://www.ics.uci.edu/~eppstein/PADS/DFS.py by D. Eppstein, July 2004.

@note: If a source is not specified then a source is chosen arbitrarily and repeatedly until all components in the graph are searched.

dace.sdfg.utils.dfs_topological_sort(G, sources=None, condition=None)

Produce nodes in a depth-first topological ordering.

The function produces nodes in a depth-first topological ordering (DFS to make sure maps are visited properly), with the condition that each node visited had all its predecessors visited. Applies for DAGs only, but works on any directed graph.

Parameters:
  • G – An input DiGraph (assumed acyclic).
  • sources – (optional) node or list of nodes that specify starting point(s) for depth-first search and return edges in the component reachable from source.
Returns:

A generator of nodes in the lastvisit depth-first-search.

@note: Based on http://www.ics.uci.edu/~eppstein/PADS/DFS.py by D. Eppstein, July 2004.

@note: If a source is not specified then a source is chosen arbitrarily and repeatedly until all components in the graph are searched.

dace.sdfg.utils.dynamic_map_inputs(state: dace.sdfg.state.SDFGState, map_entry: dace.sdfg.nodes.MapEntry) → List[dace.sdfg.graph.MultiConnectorEdge]

For a given map entry node, returns a list of dynamic-range input edges. :param state: The state in which the map entry node resides. :param map_entry: The given node. :return: A list of edges in state whose destination is map entry and denote

dynamic-range input memlets.
dace.sdfg.utils.find_input_arraynode(graph, edge)
dace.sdfg.utils.find_output_arraynode(graph, edge)
dace.sdfg.utils.find_sink_nodes(graph)

Finds the sink nodes of a graph.

The function finds the sink nodes of a graph, i.e. the nodes with zero out-degree.

Parameters:graph – The graph whose sink nodes are being searched for.
Returns:A list of the sink nodes found.
dace.sdfg.utils.find_source_nodes(graph)

Finds the source nodes of a graph.

The function finds the source nodes of a graph, i.e. the nodes with zero in-degree.

Parameters:graph – The graph whose source nodes are being searched for.
Returns:A list of the source nodes found.
dace.sdfg.utils.fuse_states(sdfg: dace.sdfg.sdfg.SDFG) → int

Fuses all possible states of an SDFG (and all sub-SDFGs) using an optimized routine that uses the structure of the StateFusion transformation. :param sdfg: The SDFG to transform. :return: The total number of states fused.

dace.sdfg.utils.get_view_edge(state: dace.sdfg.state.SDFGState, view: dace.sdfg.nodes.AccessNode) → Tuple[dace.sdfg.nodes.AccessNode, dace.sdfg.graph.MultiConnectorEdge[dace.memlet.Memlet][dace.memlet.Memlet]]

Given a view access node, returns the viewed access node and incoming/outgoing edge which points to it. See the ruleset in the documentation of dace.data.View.

Parameters:
  • state – The state in which the view resides.
  • view – The view access node.
Returns:

An edge pointing to the viewed data or None if view is invalid.

See:

dace.data.View

dace.sdfg.utils.has_dynamic_map_inputs(state: dace.sdfg.state.SDFGState, map_entry: dace.sdfg.nodes.MapEntry) → bool

Returns True if a map entry node has dynamic-range inputs. :param state: The state in which the map entry node resides. :param map_entry: The given node. :return: True if there are dynamic-range input memlets, False otherwise.

dace.sdfg.utils.is_array_stream_view(sdfg: dace.sdfg.sdfg.SDFG, dfg: dace.sdfg.state.SDFGState, node: dace.sdfg.nodes.AccessNode)

Test whether a stream is directly connected to an array.

dace.sdfg.utils.is_parallel(state: dace.sdfg.state.SDFGState, node: Optional[dace.sdfg.nodes.Node] = None) → bool

Returns True if a node or state are contained within a parallel section. :param state: The state to test. :param node: An optional node in the state to test. If None, only checks

state.
Returns:True if the state or node are located within a map scope that is scheduled to run in parallel, False otherwise.
dace.sdfg.utils.load_precompiled_sdfg(folder: str)

Loads a pre-compiled SDFG from an output folder (e.g. “.dacecache/program”). Folder must contain a file called “program.sdfg” and a subfolder called “build” with the shared object.

Parameters:folder – Path to SDFG output folder.
Returns:A callable CompiledSDFG object.
dace.sdfg.utils.local_transients(sdfg, dfg, entry_node)

Returns transients local to the scope defined by the specified entry node in the dataflow graph.

dace.sdfg.utils.merge_maps(graph: dace.sdfg.state.SDFGState, outer_map_entry: dace.sdfg.nodes.MapEntry, outer_map_exit: dace.sdfg.nodes.MapExit, inner_map_entry: dace.sdfg.nodes.MapEntry, inner_map_exit: dace.sdfg.nodes.MapExit, param_merge: Callable[[List[dace.symbolic.symbol], List[dace.symbolic.symbol]], List[dace.symbolic.symbol]] = <function <lambda>>, range_merge: Callable[[List[dace.subsets.Subset], List[dace.subsets.Subset]], List[dace.subsets.Subset]] = <function <lambda>>) -> (<class 'dace.sdfg.nodes.MapEntry'>, <class 'dace.sdfg.nodes.MapExit'>)

Merges two maps (their entries and exits). It is assumed that the operation is valid.

dace.sdfg.utils.node_path_graph(*args)

Generates a path graph passing through the input nodes.

The function generates a graph using as nodes the input arguments. Subsequently, it creates a path passing through all the nodes, in the same order as they were given in the function input.

Parameters:*args

Variable number of nodes or a list of nodes.

Returns:A directed graph based on the input arguments.

@rtype: gr.OrderedDiGraph

dace.sdfg.utils.remove_edge_and_dangling_path(state: dace.sdfg.state.SDFGState, edge: dace.sdfg.graph.MultiConnectorEdge)

Removes an edge and all of its parent edges in a memlet path, cleaning dangling connectors and isolated nodes resulting from the removal. :param state: The state in which the edge exists. :param edge: The edge to remove.

dace.sdfg.utils.separate_maps(state, dfg, schedule)

Separates the given ScopeSubgraphView into subgraphs with and without maps of the given schedule type. The function assumes that the given ScopeSubgraph view does not contain any concurrent segments (i.e. pass it through concurrent_subgraphs first). Only top level maps will be accounted for, if the desired schedule occurs in another (undesired) map, it will be ignored.

Returns a list with the subgraph views in order of the original DFG. ScopeSubgraphViews for the parts with maps, StateSubgraphViews for the parts without maps.

dace.sdfg.utils.trace_nested_access(node: dace.sdfg.nodes.AccessNode, state: dace.sdfg.state.SDFGState, sdfg: dace.sdfg.sdfg.SDFG) → List[Tuple[dace.sdfg.nodes.AccessNode, dace.sdfg.state.SDFGState, dace.sdfg.sdfg.SDFG]]

Given an AccessNode in a nested SDFG, trace the accessed memory back to the outermost scope in which it is defined.

Parameters:
  • node – An access node.
  • state – State in which the access node is located.
  • sdfg – SDFG in which the access node is located.
Returns:

A list of scopes ((input_node, output_node), (memlet_read, memlet_write), state, sdfg) in which the given data is accessed, from outermost scope to innermost scope.

dace.sdfg.validation module

Exception classes and methods for validation of SDFGs.

exception dace.sdfg.validation.InvalidSDFGEdgeError(message: str, sdfg, state_id, edge_id)

Bases: dace.sdfg.validation.InvalidSDFGError

Exceptions of invalid edges in an SDFG state.

to_json()
exception dace.sdfg.validation.InvalidSDFGError(message: str, sdfg, state_id)

Bases: Exception

A class of exceptions thrown when SDFG validation fails.

to_json()
exception dace.sdfg.validation.InvalidSDFGInterstateEdgeError(message: str, sdfg, edge_id)

Bases: dace.sdfg.validation.InvalidSDFGError

Exceptions of invalid inter-state edges in an SDFG.

to_json()
exception dace.sdfg.validation.InvalidSDFGNodeError(message: str, sdfg, state_id, node_id)

Bases: dace.sdfg.validation.InvalidSDFGError

Exceptions of invalid nodes in an SDFG state.

to_json()
exception dace.sdfg.validation.NodeNotExpandedError(sdfg: dace.sdfg.SDFG, state_id: int, node_id: int)

Bases: dace.sdfg.validation.InvalidSDFGNodeError

Exception that is raised whenever a library node was not expanded before code generation.

dace.sdfg.validation.validate(graph: dace.sdfg.graph.SubgraphView)
dace.sdfg.validation.validate_sdfg(sdfg: dace.sdfg.SDFG)

Verifies the correctness of an SDFG by applying multiple tests. :param sdfg: The SDFG to verify.

Raises an InvalidSDFGError with the erroneous node/edge on failure.

dace.sdfg.validation.validate_state(state: dace.sdfg.SDFGState, state_id: int = None, sdfg: dace.sdfg.SDFG = None, symbols: Dict[str, dace.dtypes.typeclass] = None)

Verifies the correctness of an SDFG state by applying multiple tests. Raises an InvalidSDFGError with the erroneous node on failure.

Module contents