Base.push!
— MethodAdd 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_chain
— MethodCollect 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.canonical
— MethodReturn canonical representation of a function name, e.g.:
Base.+ ==> +
Main.+ ==> + (resolved to Base.+)
Base.LinAlg.exp ==> exp
Mod.foo ==> Mod.foo
Espresso.dependencies
— MethodGet names of dependenices of this node
Espresso.dependents
— MethodFor 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.destruct
— MethodReplace 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_expr
— MethodGiven 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_codegen
— MethodFor buffered codegens, return unbuffered version that can be used in evaluate!()
Espresso.evaluate!
— MethodEvaluate node, i.e. fill its val
by evaluating node's expression using values of its dependencies.
Espresso.expand_const
— MethodExpand all constant vars in a given expression
Espresso.expand_fixed_sequences
— MethodLook at each node's dependencies and, if there are known pattern sequences, rewrite them in a more optimal way.
Espresso.find_vars
— Methodfind_vars(ex; rec=true)
Same as get_vars()
, but recursive by default
Espresso.findex
— MethodFind sub-expressions matching a pattern. Example:
ex = :(a * f(x) + b * f(y))
pat = :(f(_))
findex(pat, ex) # ==> [:(f(x)), :(f(y))]
Espresso.flatten!
— MethodFlatten vector of vectors in-place
Espresso.flatten
— MethodFlattenx vector of vectors
Espresso.flatten1
— MethodFlatten one level of nested vectors
Espresso.flatten_dots
— MethodGiven a list of expression arguments, flatten the dotted ones. Example:
args = [:foo, :([a, b, c]...)]
flatten_dots(args)
# ==> [:foo, :a, :b, :c]
Espresso.fuse_assigned
— MethodCollapse unnecessary assignment nodes, rewriting all affected nodes. Example:
tmp1 = x * y
z = tmp1
will be rewritten to
z = x * y
Espresso.genname
— MethodGenerate a new unique name for intermediate variable in graph
Espresso.get_source_at
— MethodLooks 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_vars
— MethodGet variables (Symbol
or Expr(:ref)
) involved in exprssion
Espresso.graph_hash
— MethodA single number to represent a graph. Insensitive to variable names.
Espresso.inc_var_name
— MethodGiven 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_bcast
— MethodCheck if all operations in this expression are broadcasting
Espresso.isstruct
— MethodCheck if an object is of a struct type, i.e. not a number or array
Espresso.make_call_expr
— FunctionMake call expression from function name, ordinary and keyword arguments.
The reverse of this operation is parsecallexpr()
Espresso.make_indexed
— MethodMake indexed variable. Examples:
make_indexed(:x, []) ==> :x
make_indexed(:x, [:i,:j]) ==> :(x[i,j])
See also: split_indexed
Espresso.make_subgraph
— MethodFind definition of a called function and build its subgraph ready for inlining
Espresso.matchex
— MethodMatch 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.matchingex
— MethodCheck if expression matches pattern. See matchex()
for details.
Espresso.parse!
— MethodParse Julia expression and build ExGraph in-place. Return the the output variable.
Espresso.parse_call_args
— MethodGiven a call expression, parse regular and keyword arguments
See also: split_params
Espresso.parse_call_expr
— MethodParse 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_subs
— MethodPropagate substitution rules. Example:
Dict(
:x => y,
:y => z
)
is transformed into:
Dict(
:x => z,
:y => z
)
Espresso.recover_lowered
— MethodTry 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_unused
— MethodRemoves 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.replace_inner_constr
— MethodReplace all calls to an inner constructor with the corresponding outer constructor
Espresso.rewrite
— Methodrewrite(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_all
— Methodrewrite_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_all
— Methodrewrite_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.simplify
— MethodSimplify 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_indexed
— MethodSplit 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_params
— MethodSplit parameters of a function signature, returning a list of (param name, param type) tuples and a list of keyword parameters.
See also: parsecallargs
Espresso.subs
— MethodSubstitute 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_einsum_expr
— MethodConvert ExNode to a fortmat compatible with Einsum.jl
Espresso.to_expr
— MethodConvert ExNode to a full expression, e.g. for vectorized notation:
z = x + y
or for indexed notation:
z[i] = x[i] + y[i]
Espresso.to_expr_kw
— MethodSame as to_expr(ExNode), but includes keyword arguments if any
Espresso.topsort
— MethodSort graph topologically
Espresso.tryrewrite
— MethodSame as rewrite, but returns Union{Expr, Void} and doesn't throw an error when expression doesn't match pattern
Espresso.with_indices
— MethodGenerate index names and make an indexed variable using them
Espresso.without
— MethodRemove rpatpression conforming to a pattern. Example:
ex = :(x * (m == n))
pat = :(_i == _j)
ex = without(ex, pat) # ==> :x
Espresso.without_keywords
— MethodRemove all :kw and :parameters nodes from a call expression
Espresso.@get
— MacroSame as get
function, but evaluates default_expr only if needed
Espresso.@get_array
— MacroGet 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_create
— MacroSame as @get
, but creates new object from default_expr
if it didn't exist before
Espresso.@get_or_return
— MacroSame as @get
, but immediately exits function and return default_expr
if key doesn't exist.
Espresso.@simple_rule
— MacroMacro 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.@tracked
— MacroDefine 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
.