Base.push!Method

Add a new node to a graph. Expression should be simple, e.g. nested calls or blocks are not allowed (use parse!() for it).

Espresso.assign_chainMethod

Collect all replacable variables from a chain of assignments in a graph. Variables y and x are considered replacable if there's a node y = x and both variables have the same set of guards. Note that this allows nodes to have different sets of indices.

Espresso.canonicalMethod

Return canonical representation of a function name, e.g.:

Base.+  ==> +
Main.+  ==> + (resolved to Base.+)
Base.LinAlg.exp ==> exp
Mod.foo ==> Mod.foo
Espresso.dependentsMethod

For each variable in graph, calculate all variables that depend on it. This is essentially the opposite of dependencies(nd::ExNode), but operates on variable names rather than nodes.

Espresso.destructMethod

Replace all struct arguments by a list of their plain analogues. Example:

args = [:m, :x, :y]
types = (Linear, Matrix{Float64}, Matrix{Float64})
ex = :(sum((m.W * x .+ m.b) - y))

destruct(args, types, ex)
# ==>
# ([:m_W, :m_b, :x, :y],
#  :(sum((m_W * x .+ m_b) - y)),
#  Dict(:(m.W) => :m_W, :(m.b) => :m_b))
Espresso.dot_exprMethod

Given a list of symbols such as [:x, :y, :z] constructs expression x.y.z. This is useful for building expressions of qualified names such as Base.LinAlg.exp.

Espresso.eval_codegenMethod

For buffered codegens, return unbuffered version that can be used in evaluate!()

Espresso.evaluate!Method

Evaluate node, i.e. fill its val by evaluating node's expression using values of its dependencies.

Espresso.find_varsMethod

find_vars(ex; rec=true)

Same as get_vars(), but recursive by default

Espresso.findexMethod

Find sub-expressions matching a pattern. Example:

ex = :(a * f(x) + b * f(y))
pat = :(f(_))
findex(pat, ex)   # ==> [:(f(x)), :(f(y))]
Espresso.flatten_dotsMethod

Given a list of expression arguments, flatten the dotted ones. Example:

args = [:foo, :([a, b, c]...)]
flatten_dots(args)
# ==> [:foo, :a, :b, :c]
Espresso.fuse_assignedMethod

Collapse unnecessary assignment nodes, rewriting all affected nodes. Example:

tmp1 = x * y
z = tmp1

will be rewritten to

z = x * y
Espresso.gennameMethod

Generate a new unique name for intermediate variable in graph

Espresso.get_source_atMethod

Looks up the source of method in the file path found in method. Returns the AST and source string, might throw an LoadError if file not found.

Espresso.get_varsMethod

Get variables (Symbol or Expr(:ref)) involved in exprssion

Espresso.graph_hashMethod

A single number to represent a graph. Insensitive to variable names.

Espresso.inc_var_nameMethod

Given a symbolic name, either adds 2 to the end or increment existing number. Example:

inc_var_name(:x)   # ==> x2
inc_var_name(:x2)  # ==> x3
Espresso.is_bcastMethod

Check if all operations in this expression are broadcasting

Espresso.isstructMethod

Check if an object is of a struct type, i.e. not a number or array

Espresso.make_call_exprFunction

Make call expression from function name, ordinary and keyword arguments.

The reverse of this operation is parsecallexpr()

Espresso.make_indexedMethod

Make indexed variable. Examples:

make_indexed(:x, [])       ==> :x
make_indexed(:x, [:i,:j])  ==> :(x[i,j])

See also: split_indexed

Espresso.make_subgraphMethod

Find definition of a called function and build its subgraph ready for inlining

Espresso.matchexMethod

Match expression ex to a pattern pat, return nullable dictionary of matched symbols or rpatpressions. Example:

ex = :(u ^ v)
pat = :(_x ^ _n)
matchex(pat, ex)
# ==> Union{ Dict{Symbol,Any}(:_n=>:v,:_x=>:u), Void }

NOTE: two symbols match if they are equal or symbol in pattern is a placeholder. Placeholder is any symbol that starts with ''. It's also possible to pass list of placeholder names (not necessarily starting wiht '') via phs parameter:

ex = :(u ^ v)
pat = :(x ^ n)
matchex(pat, ex; phs=Set([:x, :n]))
# ==> Union{ Dict{Symbol,Any}(:n=>:v,:x=>:u), Void } 

Several elements may be matched using ... expression, e.g.:

ex = :(A[i, j, k])
pat = :(x[I...])
matchex(pat, ex; phs=Set([:x, :I]))
# ==> Union{ Dict(:x=>:A, :I=>[:i,:j,:k]), Void }

Optional parameters:

  • phs::Set{Symbol} = DEFAULT_PHS[1] A set of placeholder symbols

  • allow_ex::Boolean = true Allow matchinng of symbol pattern to an expression. Example:

        matchex(:(_x + 1), :(a*b + 1); allow_ex=true)  # ==> matches
        matchex(:(_x + 1), :(a*b + 1); allow_ex=false)  # ==> doesn't match
  • exact::Boolean = false Allow matching of the same expression to different keys

        matchex(:(_x + _y), :(a + a); exact=false) # ==> matches
        matchex(:(_x = _y), :(a + a); exact=true)  # ==> doesn't match
Espresso.parse!Method

Parse Julia expression and build ExGraph in-place. Return the the output variable.

Espresso.parse_call_exprMethod

Parse call expression into function name, ordinary and keyword arguments. :kw and :parameters arguments are treated the same way.

The reverse of this operation is makecallexpr()

Espresso.prop_subsMethod

Propagate substitution rules. Example:

Dict(
    :x => y,
    :y => z
)

is transformed into:

Dict(
    :x => z,
    :y => z
)
Espresso.recover_loweredMethod

Try to recover an expression from a lowered form. Example:

ex = (Main.sum)((Base.literal_pow)(Main.^, (Base.broadcast)(Main.-, (Main.predict)(W, b, x), y), (Core.apply_type)(Base.Val, 2)))
Espresso.remove_unusedMethod

Removes unused variables from multiline expressions, e.g. in:

x = u * v
y = x + 1
z = 2x

y isn't used to compute output variable z, so it's removed:

x = u * v
z = 2x
Espresso.rewriteMethod

rewrite(ex, pat, rpat)

Rewrite expression ex according to a transform from pattern pat to a substituting expression rpat. Example (derivative of x^n):

ex = :(u ^ v)
pat = :(_x ^ _n)
rpat = :(_n * _x ^ (_n - 1))
rewrite(ex, pat, rpat) # ==> :(v * u ^ (v - 1))
Espresso.rewrite_allMethod

rewrite_all(ex, rules)

Recursively rewrite an expression according to a list of rules like [pat => rpat] Example:

ex = :(foo(bar(foo(A))))
rules = [:(foo(x)) => :(quux(x)),
         :(bar(x)) => :(baz(x))]
rewrite_all(ex, rules; phs=[:x])
# ==> :(quux(baz(quux(A))))
Espresso.rewrite_allMethod

rewrite_all(ex, pat, rpat)

Recursively rewrite all occurrences of a pattern in an expression. Example:

ex = :(foo(bar(foo(A))))
pat = :(foo(x))
rpat = :(quux(x))
rewrite_all(ex, pat, rpat; phs=[:x])
# ==> :(quux(bar(quux(A))))
Espresso.simplifyMethod

Simplify expression x by applying a set of rules. Common examples of simplification include calculation of fully numeric subexpressions, removing needless multiplication by 1, etc.

Use macro @simple_rule to add new simplification rules.

Espresso.split_indexedMethod

Split possibly indexed variable into a name and indices. Examples:

split_indexed(:x)         ==> (:x, [])
split_indexed(:(x[i,j]))  ==> (:x, [:i,:j])

See also: make_indexed

Espresso.split_paramsMethod

Split parameters of a function signature, returning a list of (param name, param type) tuples and a list of keyword parameters.

See also: parsecallargs

Espresso.subsMethod

Substitute symbols in ex according to substitute table st. Example:

ex = :(x ^ n)
subs(ex, x=2)            # ==> :(2 ^ n)

alternatively:

subs(ex, Dict(:x => 2))  # ==> :(2 ^ n)

If ex contains a :(xs...) argument and st contains an array-valued sabstitute for it, the substitute will be flattened:

ex = :(foo(xs...))
subs(ex, Dict(:xs => [:a, :b, :c]))
# ==> :(foo(a, b, c))
Espresso.to_exprMethod

Convert ExNode to a full expression, e.g. for vectorized notation:

z = x + y

or for indexed notation:

z[i] = x[i] + y[i]
Espresso.tryrewriteMethod

Same as rewrite, but returns Union{Expr, Void} and doesn't throw an error when expression doesn't match pattern

Espresso.withoutMethod

Remove rpatpression conforming to a pattern. Example:

ex = :(x * (m == n))
pat = :(_i == _j)
ex = without(ex, pat)  # ==> :x
Espresso.@getMacro

Same as get function, but evaluates default_expr only if needed

Espresso.@get_arrayMacro

Get array of size sz from a dict by key. If element doesn't exist or its size is not equal to sz, create and return new array using default_expr. If element exists, but is not an error, throw ArgumentError.

Espresso.@get_or_returnMacro

Same as @get, but immediately exits function and return default_expr if key doesn't exist.

Espresso.@simple_ruleMacro

Macro to add simplification rules. Example:

@simple_rule (-x * -y) (x * y)

where (-x * -y) is a pattern to match expression and (x * y) is what it should be transformed to (see rewrite() to understand expression rewriting). Symbols Set([:a, :b, :y, :x]) may be used as placeholders when defining new rules, all other symbols will be taken literally.

Espresso.@trackedMacro

Define a function or broadcasting rule for the specified signature which computes the result as for ordinary (not tracked) data and writes it to the graph.

Note: this function expects at least 1 parameter of TrackedReal or TrackedArray type with name x.