fluxml / mjolnir.jl Goto Github PK
View Code? Open in Web Editor NEWA little less conversation, a little more abstraction
License: Other
A little less conversation, a little more abstraction
License: Other
Hi there,
Thanks for this very cool library!
I'm trying to use this library in some code involving sparse matrix multiplication and ran into some issues. Since I'm using Julia 1.6, I had to use Mjolnir.jl
from PR #34 with IRTools#master
as suggested by @pabloferz.
The code
function mymul!(C::Matrix{Float64}, A::SparseMatrixCSC{Float64, Int64}, B::Matrix{Float64})
nzv = nonzeros(A)
rv = rowvals(A)
for k in 1:size(C, 2)
@inbounds for col in 1:size(A, 2)
for j in nzrange(A, col)
C[rv[j], k] += nzv[j]*B[col,k]
end
end
end
C
end
A = sparse(Matrix{Float64}(I,10,10));
B = rand(10,10);
C = zeros(10, 10);
@trace mymul!(C, A, B)
The error
ERROR: Tracing Error: MethodError: abstract(::Mjolnir.Basic, ::Mjolnir.Const{typeof(getindex)}, ::Mjolnir.Const{Vector{Int64}}, ::Mjolnir.Const{Int64}) is ambiguous. Candidates:
abstract(::Mjolnir.Basic, var"287"::Union{Mjolnir.Const{typeof(getindex)}, Mjolnir.Node{typeof(getindex)}, Type{typeof(getindex)}, Mjolnir.Partial{typeof(getindex)}, Mjolnir.Shape{typeof(getindex)}}, xs::Mjolnir.Const{var"#s40"} where var"#s40"<:Array, i::Mjolnir.Const...) in Mjolnir at /Users/matthieubulte/.julia/packages/Mjolnir/yjFab/src/macros.jl:55
abstract(::Mjolnir.Basic, var"301"::Union{Mjolnir.Const{typeof(getindex)}, Mjolnir.Node{typeof(getindex)}, Type{typeof(getindex)}, Mjolnir.Partial{typeof(getindex)}, Mjolnir.Shape{typeof(getindex)}}, xs::Union{Type{var"#s28"}, Mjolnir.Const{var"#s28"}, Mjolnir.Node{var"#s28"}, Mjolnir.Partial{var"#s28"}, Mjolnir.Shape{var"#s28"}} where var"#s28"<:(AbstractArray{T, N} where N), is::Union{Type{var"#s8"}, Mjolnir.Const{var"#s8"}, Mjolnir.Node{var"#s8"}, Mjolnir.Partial{var"#s8"}, Mjolnir.Shape{var"#s8"}} where var"#s8"<:Integer...) where T in Mjolnir at /Users/matthieubulte/.julia/packages/Mjolnir/yjFab/src/macros.jl:55
To resolve the ambiguity, try making one of the methods more specific, or adding a new method more specific than any of the existing applicable methods.
in Tuple{typeof(mymul!), Int64, Matrix{Float64}, SparseMatrixCSC{Float64, Int64}, Matrix{Float64}}
in Tuple{typeof(nzrange), SparseMatrixCSC{Float64, Int64}, Int64}
Stacktrace:
[1] trace(::Any, ::Any, ::Vararg{Any, N} where N)
@ Mjolnir ~/.julia/packages/Mjolnir/yjFab/src/trace.jl:268
[2] top-level scope
@ REPL[53]:1
I'm not quite sure if this is an issue from the code I'm trying to trace, or if this is a bug, so please let me know if I did something stupid.
Cheers,
Matthieu
This is currently breaking Flux, Zygote, etc in my lib.
Hello Mike,
In the spirit of your readme, I'm wondering to what extent this package can or is intended to address some common pain points aside from speeding up flux/zygote:
For those that apply, are they planned roadmap items, and if not, how much additional work would they required?
Thanks
Right now, it's a little difficult to tell exactly what each test is testing for (at least for me, someone who is only slightly familiar with intrinsics + Base).
needs support
I tried to do nothing in this case like in :meta
but that fails.
julia> g(x) = @inbounds for i=eachindex(x); x[i] += 1; end
julia> @trace g([1,2,3])
ERROR: Tracing Error: Can't trace through inbounds expression
in Tuple{typeof(g),Array{Int64,1}}
Stacktrace:
[1] trace(::Mjolnir.Multi{Tuple{Mjolnir.Basic,Mjolnir.Numeric}}, ::Mjolnir.Const{typeof(g)}, ::Vararg{Any,N} where N) at /home/shashi/.julia/dev/Mjolnir/src/trace.jl:248
[2] top-level scope at REPL[30]:1
[3] run_backend(::REPL.REPLBackend) at /home/shashi/.julia/packages/Revise/MgvIv/src/Revise.jl:1023
[4] top-level scope at none:0
caused by [exception 1]
Can't trace through inbounds expression
Stacktrace:
[1] traceblock!(::Mjolnir.Trace, ::Dict{Any,Any}, ::IRTools.Inner.Block)
julia> g(x) = for i=eachindex(x); x[i] += 1; end
g (generic function with 1 method)
julia> @trace g([1,2,3])
ERROR: Tracing Error: No IR for Tuple{typeof(getfield),Union{Nothing, Tuple{Int64,Int64}},Int64}
in Tuple{typeof(g),Array{Int64,1}}
in Tuple{typeof(getfield),Union{Nothing, Tuple{Int64,Int64}},Int64}
Stacktrace:
[1] trace(::Mjolnir.Multi{Tuple{Mjolnir.Basic,Mjolnir.Numeric}}, ::Mjolnir.Const{typeof(g)}, ::Vararg{Any,N} where N) at /home/shashi/.julia/dev/Mjolnir/src/trace.jl:249
[2] top-level scope at REPL[26]:1
[3] run_backend(::REPL.REPLBackend) at /home/shashi/.julia/packages/Revise/MgvIv/src/Revise.jl:1023
[4] top-level scope at none:0
caused by [exception 1]
No IR for Tuple{typeof(getfield),Union{Nothing, Tuple{Int64,Int64}},Int64}
Stacktrace:
[1] tracecall!(::Mjolnir.Trace, ::Array{Any,1}, ::Mjolnir.Const{typeof(getfield)}, ::Vararg{Any,N} where N) at /home/shashi/.julia/dev/Mjolnir/src/trace.jl:212
[2] traceblock!(::Mjolnir.Trace, ::Dict{Any,Any}, ::IRTools.Inner.Block) at /home/shashi/.julia/dev/Mjolnir/src/trace.jl:172
related to #4 (I think).
Maybe this can be fixed by making trace try all the options in the union separately and then trying to do a union of the types.
https://github.com/MikeInnes/Mjolnir.jl/blob/master/docs/types.md is a fantastic guide!
It would be also nice to have docstrings for:
trace
@trace
return_type
@abstract
IR
document more of what it contains, and how to access parts of it.AType
So that it's easy to look up what the arguments should be.
MWE:
using Mjolnir, IRTools
function foo()
for i in 2:3
2 + 3
end
return
end
ir = @code_ir foo()
Mjolnir.return_type(ir)
I think this should return Nothing
or at least trigger the iterate error in #7 but this gives me
ERROR: DimensionMismatch("array could not be broadcast to match destination")
on current master.
My first spin of Mjölner, encountered a mysterious error. Please forgive me if I've been using it wrong
julia> function negsquare(x)
if x > 0
return x^2
else
return -x^2
end
end
negsquare (generic function with 1 method)
julia> using Mjolnir
julia> negsquare(1.0)
1.0
julia> code = @trace negsquare(1.0)
1: (%1 :: const(negsquare), %2 :: const(1.0))
return 1.0
julia> code = @trace negsquare(::Float64)
ERROR: Tracing Error: UndefVarError: inline not defined
in Tuple{typeof(negsquare),Float64}
Stacktrace:
[1] trace(::Any, ::Any, ::Vararg{Any,N} where N) at /home/fredrikb/.julia/packages/Mjolnir/WikP6/src/trace.jl:272
[2] top-level scope at none:1
Example: (_propagate
calls trace
under the hood).
function burglary_model(x::Float64)
burglary = trace(:burglary, Bernoulli(0.05))
burglary ? disabled = trace(:disabled, Bernoulli(0.1)) : disabled = false
!disabled ? alarm = trace(:alarm, Bernoulli(burglary ? 0.94 : 0.01)) : alarm = false
call = trace(:call, Bernoulli(alarm ? 0.70 : 0.05))
return nothing
end
tr = Jaynes._propagate(typeof(burglary_model), (Float64, ), (NoChange(), ))
display(tr)
produces
1: (%1 :: typeof(Main.BurglaryModel.burglary_model), %2 :: Gen.NoChange())
%3 = (Distributions.Bernoulli)(0.05) :: Gen.NoChange
%4 = (Main.BurglaryModel.Jaynes.trace)(:burglary, %3) :: Gen.NoChange
br 3 unless %4
br 2
2:
%5 = (Distributions.Bernoulli)(0.1) :: Gen.NoChange
%6 = (Main.BurglaryModel.Jaynes.trace)(:disabled, %5) :: Gen.NoChange
br 4 (%6)
3:
br 4 (false)
4: (%7 :: Union{Gen.NoChange, Bool})
%8 = (!)(%7) :: Bool
br 7 unless %8
br 6 unless %4
br 5
5:
%9 = (Distributions.Bernoulli)(0.94) :: Union{}
%10 = (Main.BurglaryModel.Jaynes.trace)(:alarm, %9) :: Union{}
br 8
6:
%11 = (Distributions.Bernoulli)(0.01) :: Union{}
%12 = (Main.BurglaryModel.Jaynes.trace)(:alarm, %11) :: Union{}
br 8
7:
br 8
8:
%13 = (Distributions.Bernoulli)(0.05) :: Gen.NoChange
%14 = (Main.BurglaryModel.Jaynes.trace)(:call, %13) :: Gen.NoChange
return nothing
Completely missing blocks 5 and 6 from burglary ? 0.94 : 0.01
.
The following triggers an infinite loop.
function pow(x, n)
n == one(n) && return x
n <= zero(n) && return zero(x)
return x*pow(x, n-1)
end
using Mjolnir
@trace pow(Float64, Int)
This is pretty interesting:
1: (%1, %2)
%3 = Main.MjolnirUpdate.Normal(%2, 1.0)
%4 = (IRTools.Inner.Self())(Main.MjolnirUpdate.rand, :m, %3)
return %4
1: (%1, %2)
%3 = Main.MjolnirUpdate.Normal(%2, 1.0)
%4 = (IRTools.Inner.Self())(Main.MjolnirUpdate.rand, :m, %3)
return %4
Internal error: encountered unexpected error in runtime:
BoundsError(a=Array{Symbol, (2,)}[
Symbol("#self#"),
:args], i=(3,))
jl_bounds_error_ints at /buildworker/worker/package_linux64/build/src/rtutils.c:183
I'm dumping out the IR, and I'm able to exactly match the IR from tracing with Mjolnir vs an IRTools dynamo (recurse! applied to both) - but the first segfaults with a BoundsError.
Hi, great package!
Is it possible to run traced code like IRTools.func
?
Sometimes I get an evaluation, but sometimes Julia just crashes:
function pow(x, n)
r = 1
while n > 0
n -= 1
r *= x
end
return r
end
tr = @trace pow(::Int,::Int)
f = IRTools.func(tr)
f(2,10) # crash
Cheers,
A
I've found that when I trace a function where the number of iterations of a loop is passed in as an ::Int
, things break. for instance;
julia> function m(n)
for i = 1:n
nothing
end
end
m (generic function with 1 method)
julia> @trace m(::Int)
ERROR: Tracing Error: Unrecognised expression $(QuoteNode(Int64))
in Tuple{typeof(m),Int64}
in Tuple{typeof(iterate),UnitRange{Int64}}
Stacktrace:
[1] trace(::Any, ::Any, ::Vararg{Any,N} where N) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:268
[2] top-level scope at REPL[51]:1
caused by [exception 1]
Unrecognised expression $(QuoteNode(Int64))
Stacktrace:
[1] error(::String) at ./error.jl:33
[2] step!(::Mjolnir.Inference) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/infer.jl:200
[3] infer!(::Mjolnir.Inference) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/infer.jl:225
[4] abstract!(::Any, ::Any, ::Any) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:136
[5] trace!(::Mjolnir.Trace, ::Any, ::Any) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:220
[6] tracecall!(::Mjolnir.Trace, ::Any, ::Any, ::Vararg{Any,N} where N) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:231
[7] traceblock!(::Mjolnir.Trace, ::Any, ::Any) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:189
[8] trace!(::Mjolnir.Trace, ::Any, ::Any) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:213
[9] tracecall!(::Mjolnir.Trace, ::Any, ::Any, ::Vararg{Any,N} where N) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:231
[10] trace(::Any, ::Any, ::Vararg{Any,N} where N) at /Users/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:263
[11] top-level scope at REPL[51]:1
julia> versioninfo()
Julia Version 1.6.3
Commit ae8452a9e0 (2021-09-23 17:34 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E3-1245 v3 @ 3.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-11.0.1 (ORCJIT, haswell)
(scratch) pkg> add Mjolnir
Updating registry at `~/.julia/registries/General`
Updating git-repo `https://github.com/JuliaRegistries/General.git`
Resolving package versions...
Updating `~/Tutorials/Julia/scratch/Project.toml`
[1154507a] + Mjolnir v0.2.1
Updating `~/Tutorials/Julia/scratch/Manifest.toml`
[7869d1d1] + IRTools v0.4.4
[1914dd2f] + MacroTools v0.5.9
[1154507a] + Mjolnir v0.2.1
[2a0f44e3] + Base64
[b77e0a4c] + InteractiveUtils
[56ddb016] + Logging
[d6f4376e] + Markdown
[9a3f8284] + Random
[9e88b42a] + Serialization
[8dfed614] + Test
(scratch) pkg> test Mjolnir
(scratch) pkg> test Mjolnir
Testing Mjolnir
Status `/tmp/jl_Nclk2z/Project.toml`
[7869d1d1] IRTools v0.4.4
[1914dd2f] MacroTools v0.5.9
[1154507a] Mjolnir v0.2.1
[8dfed614] Test `@stdlib/Test`
Status `/tmp/jl_Nclk2z/Manifest.toml`
[7869d1d1] IRTools v0.4.4
[1914dd2f] MacroTools v0.5.9
[1154507a] Mjolnir v0.2.1
[2a0f44e3] Base64 `@stdlib/Base64`
[b77e0a4c] InteractiveUtils `@stdlib/InteractiveUtils`
[56ddb016] Logging `@stdlib/Logging`
[d6f4376e] Markdown `@stdlib/Markdown`
[9a3f8284] Random `@stdlib/Random`
[9e88b42a] Serialization `@stdlib/Serialization`
[8dfed614] Test `@stdlib/Test`
Testing Running tests...
Trace: Error During Test at /home/<me>/.julia/packages/Mjolnir/7FUVN/test/runtests.jl:5
Got exception outside of a @test
LoadError: Tracing Error: deepcopy of Modules not supported
in Tuple{typeof(f), Int64, Int64}
Stacktrace:
Tracing may not be possible in situations where there is no unique next method to pick to trace. But this situation should occur way less with Mjolnir as opposed to using the standard Julia type inference as can be seen in this example
For example, if you have Dict{Any,Any} – we can see all the set and getindexes, so we can infer keys of the dictionary as if they were local variables
But should document when exactly it won't work, and provide reasonable suggestions to avoid those cases.
Edit: same as #3.
Just playing around with this, I find myself writing the following a lot:
@abstract Basic f(x::T) where {T} = Core.Compiler.return_type(f, Tuple{T})
It might be nice if we just made
@abstract Basic f(x)
lower to the above.
Currently the Defaults (both Basic and Numeric put together) don't cover all the built-ins. We should try and support all of these, so other rules can build on top of a solid default tracer (basically the whole language).
It seems like the @abstract
definitions are currently provided at a higher level than builtins and intrinsics, so we can check off those that the higher level defs cover in a reasonable way.
#unsure what this is
This is pretty quickly encountered when tracing with symbolic arrays.
julia> Mjolnir.abstract(Mjolnir.Basic(), Mjolnir.Const(typeof), Mjolnir.Node{AbstractArray{Float64,2}}(Mjolnir.var(0)))
ERROR: UndefVarError: T not defined
Stacktrace:
[1] #74#f(::Union{Type{#s36}, Mjolnir.Const{#s36}, Mjolnir.Node{#s36}, Mjolnir.Partial{#s36}, Mjolnir.Shape{#s36}} where #s36<:typeof(typeof), ::Mjolnir.Node{AbstractArray{Float64,2}}) at /home/shashi/.julia/dev/Mjolnir/src/lib/base.jl:15
[2] abstract(::Mjolnir.Basic, ::Union{Mjolnir.Const{typeof(typeof)}, Mjolnir.Node{typeof(typeof)}, Type{typeof(typeof)}, Mjolnir.Partial{typeof(typeof)}, Mjolnir.Shape{typeof(typeof)}}, ::Mjolnir.Node{AbstractArray{Float64,2}}) at /home/shashi/.julia/dev/Mjolnir/src/macros.jl:58
[3] top-level scope at REPL[21]:1
[4] run_backend(::REPL.REPLBackend) at /home/shashi/.julia/packages/Revise/tV8FE/src/Revise.jl:1165
[5] top-level scope at none:0
julia> ir = @code_ir 1+2 [3/281]
1: (%1, %2, %3) %4 = Base.add_int(%2, %3)
return %4
julia> Mjolnir.return_type(ir, Nothing, Int, Int)
ERROR: No IR for Tuple{Core.IntrinsicFunction,Int64,Int64}
Stacktrace:
[1] infercall!(::Mjolnir.Inference, ::Tuple{Mjolnir.Frame,Int64,Int64,Int64}, ::IRTools.Inner.Block, ::Expr
) at /home/shashi/.julia/dev/Mjolnir/src/infer.jl:130
[2] step!(::Mjolnir.Inference) at /home/shashi/.julia/dev/Mjolnir/src/infer.jl:168
[3] infer!(::Mjolnir.Inference) at /home/shashi/.julia/dev/Mjolnir/src/infer.jl:197
[4] return_type(::IRTools.Inner.IR, ::Type{T} where T, ::Vararg{Type{T} where T,N} where N) at /home/shashi
/.julia/dev/Mjolnir/src/infer.jl:226
[5] top-level scope at REPL[13]:1
[6] run_backend(::REPL.REPLBackend) at /home/shashi/.julia/packages/Revise/Pcs5V/src/Revise.jl:1073
I have 2 questions here:
add(a,b) = a+b
and infer on that.return_type
Nothing?
g(x, y) = x * 2 + y * 3
jjulia> @trace g(::Int, ::Int)
ERROR: Tracing Error: deepcopy of Modules not supported
in Tuple{typeof(g), Int64, Int64}
Stacktrace:
[1] trace(::Any, ::Any, ::Vararg{Any, N} where N)
@ Mjolnir ~/repos/Mjolnir.jl/src/trace.jl:268
[2] top-level scope
@ REPL[16]:1
caused by: deepcopy of Modules not supported
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:33
[2] deepcopy_internal(x::Module, stackdict::IdDict{Any, Any})
@ Base ./deepcopy.jl:33
[3] deepcopy_internal(x::Any, stackdict::IdDict{Any, Any})
@ Base ./deepcopy.jl:76
[4] _deepcopy_array_t(x::Array, T::Type, stackdict::IdDict{Any, Any})
@ Base ./deepcopy.jl:105
[5] deepcopy_internal(x::Vector{Core.LineInfoNode}, stackdict::IdDict{Any, Any})
@ Base ./deepcopy.jl:92
[6] deepcopy_internal(x::Any, stackdict::IdDict{Any, Any})
@ Base ./deepcopy.jl:76
[7] deepcopy(x::IRTools.Inner.IR)
@ Base ./deepcopy.jl:26
[8] getir(::Mjolnir.Trace, ::Any, ::Vararg{Any, N} where N)
@ Mjolnir ~/repos/Mjolnir.jl/src/trace.jl:18
[9] tracecall!(::Mjolnir.Trace, ::Any, ::Any, ::Vararg{Any, N} where N)
@ Mjolnir ~/repos/Mjolnir.jl/src/trace.jl:228
[10] trace(::Any, ::Any, ::Vararg{Any, N} where N)
@ Mjolnir ~/repos/Mjolnir.jl/src/trace.jl:263
[11] top-level scope
@ REPL[16]:1
julia> function f(x)
if x > 0
k = 0
while k < 10
k += 1
x = x * 4
end
else
j = 0
while j < 5
j += 1
x = x + 4
end
end
x
end
f (generic function with 1 method)
julia> @trace f(::Int)
ERROR: Tracing Error: KeyError: key %58 not found
Stacktrace:
[1] trace(::Any, ::Any, ::Vararg{Any,N} where N) at /home/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:268
[2] top-level scope at REPL[29]:1
caused by [exception 1]
KeyError: key %58 not found
Stacktrace:
[1] getindex at ./dict.jl:467 [inlined]
[2] substitute at /home/zenna/.julia/packages/IRTools/GVPoj/src/ir/ir.jl:853 [inlined]
[3] _broadcast_getindex_evalf(::typeof(IRTools.Inner.substitute), ::IRTools.Inner.Pipe, ::IRTools.Inner.Variable) at ./broadcast.jl:648
[4] _broadcast_getindex(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(IRTools.Inner.substitute),Tuple{Tuple{IRTools.Inner.Pipe},Base.Broadcast.Extruded{Array{Any,1},Tuple{Bool},Tuple{Int64}}}}, ::Int64) at ./broadcast.jl:621
[5] getindex at ./broadcast.jl:575 [inlined]
[6] copyto_nonleaf!(::Array{typeof(<),1}, ::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(IRTools.Inner.substitute),Tuple{Tuple{IRTools.Inner.Pipe},Base.Broadcast.Extruded{Array{Any,1},Tuple{Bool},Tuple{Int64}}}}, ::Base.OneTo{Int64}, ::Int64, ::Int64) at ./broadcast.jl:1026
[7] copy(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(IRTools.Inner.substitute),Tuple{Tuple{IRTools.Inner.Pipe},Array{Any,1}}}) at ./broadcast.jl:880
[8] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(IRTools.Inner.substitute),Tuple{Tuple{IRTools.Inner.Pipe},Array{Any,1}}}) at ./broadcast.jl:837
[9] substitute(::IRTools.Inner.Pipe, ::Expr) at /home/zenna/.julia/packages/IRTools/GVPoj/src/ir/ir.jl:856
[10] substitute(::IRTools.Inner.Pipe, ::IRTools.Inner.Statement) at /home/zenna/.julia/packages/IRTools/GVPoj/src/ir/ir.jl:855
[11] iterate(::IRTools.Inner.Pipe, ::Any) at /home/zenna/.julia/packages/IRTools/GVPoj/src/ir/ir.jl:892
[12] iterate(::IRTools.Inner.Pipe, ::Any) at /home/zenna/.julia/packages/IRTools/GVPoj/src/ir/ir.jl:888
[13] renumber(::Any) at /home/zenna/.julia/packages/IRTools/GVPoj/src/passes/passes.jl:124
[14] |> at ./operators.jl:834 [inlined]
[15] cleanup!(::Any) at /home/zenna/.julia/packages/Mjolnir/7FUVN/src/cleanup.jl:91
[16] trace(::Any, ::Any, ::Vararg{Any,N} where N) at /home/zenna/.julia/packages/Mjolnir/7FUVN/src/trace.jl:266
[17] top-level scope at REPL[29]:1
I'm interested in using Mjolnir to transpile Julia to GLSL shaders. Since JSExpr implements a javascript AST I though it would be a good stepping stone to create a minimal example of transpiling to javascript first. How would I transpile the following julia code
function adder(x, y)
x + y
end
function multiplier(x, y)
x * y
end
function nested(x, y)
multiplier(x, adder(x, y))
end
into the equivalent javascript?
function adder(x, y){
return x+y;
}
function multiplier(x, y){
return x * y;
}
function nested(x, y){
return multiplier(x, adder(x, y));
}
Thus far I've come up with this:
using Mjolnir
using JSExpr
using IRTools.Inner: IR, BasicBlock, Statement
import JSExpr: crawl
function JSEpr.crawl(trace::IR)
crawl.(blocks)
end
function JSEpr.crawl(block::BasicBlock)
statements = crawl.(block.stmts)
end
function JSEpr.crawl(statement::Statement)
crawl(statement.expr)
end
Current, it seems that @trace f(Int)
means the same thing as @trace f(x::Int)
, but that seems to be kind of ambiguous. What if I meant for f(T)
to be a function that takes in a type (in this case, Int
) and I wanted to trace f
with Int
as a Const
?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.