Skip to content

Commit a1f72ef

Browse files
committed
Adjust to compiler excision
1 parent 06cb7dd commit a1f72ef

16 files changed

+95
-86
lines changed

Project.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
name = "Diffractor"
22
uuid = "9f5e2b26-1114-432f-b630-d3fe2085c51c"
3-
authors = ["Keno Fischer <[email protected]> and contributors"]
43
version = "0.2.10"
4+
authors = ["Keno Fischer <[email protected]> and contributors"]
55

66
[deps]
77
AbstractDifferentiation = "c29ec348-61ec-40c8-8164-b8c60e9d9f3d"
88
ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2"
99
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
1010
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
11+
Compiler = "807dbc54-b67e-4c79-8afb-eafe4df6f2e1"
1112
Cthulhu = "f68482b8-f384-11e8-15f7-abe071a5a75f"
1213
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
1314
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
@@ -20,6 +21,7 @@ AbstractDifferentiation = "0.5, 0.6"
2021
ChainRules = "1.44.6"
2122
ChainRulesCore = "1.20"
2223
Combinatorics = "1"
24+
Compiler = "0.0.1"
2325
Cthulhu = "2.10.1"
2426
OffsetArrays = "1"
2527
PrecompileTools = "1"

src/Diffractor.jl

+5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ export ∂⃖, gradient
55
using StructArrays
66
using PrecompileTools
77

8+
if VERSION v"1.12.0-DEV.1581"
9+
import Compiler
10+
const CC = Compiler
11+
else
812
const CC = Core.Compiler
13+
end
914
using Core.IR
1015

1116
@static if VERSION v"1.11.0-DEV.1498"

src/analysis/forward.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using Core.Compiler: StmtInfo, ArgInfo, CallMeta, AbsIntState
1+
using .CC: StmtInfo, ArgInfo, CallMeta, AbsIntState
22

33
if VERSION >= v"1.12.0-DEV.1268"
44

5-
using Core.Compiler: Future
5+
using .CC: Future
66

77
function fwd_abstract_call_gf_by_type(interp::AbstractInterpreter, @nospecialize(f),
88
arginfo::ArgInfo, si::StmtInfo, sv::AbsIntState, primal_call::Future{CallMeta})

src/codegen/forward_demand.jl

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Core.Compiler: IRInterpretationState, construct_postdomtree, PiNode,
1+
using .CC: IRInterpretationState, construct_postdomtree, PiNode,
22
is_known_call, argextype, postdominates, userefs, PhiCNode, UpsilonNode
33

44
#=
@@ -55,7 +55,7 @@ function forward_diff!(ir::IRCode, interp::AbstractInterpreter, irsv::IRInterpre
5555
end
5656

5757
function forward_diff_uncached!(ir::IRCode, interp::AbstractInterpreter, irsv::IRInterpretationState,
58-
ssa::SSAValue, inst::Core.Compiler.Instruction, order::Int;
58+
ssa::SSAValue, inst::CC.Instruction, order::Int;
5959
custom_diff!, diff_cache, eras_mode)
6060
stmt = inst[:inst]
6161
recurse(x) = forward_diff!(ir, interp, irsv, x, order; custom_diff!, diff_cache, eras_mode)
@@ -94,12 +94,12 @@ function forward_diff_uncached!(ir::IRCode, interp::AbstractInterpreter, irsv::I
9494
Δbacking = insert_node!(ir, ssa, NewInstruction(Δtpl, tup_typ))
9595
newT = argextype(stmt.args[1], ir)
9696
@assert isa(newT, Const)
97-
tup_typ_typ = Core.Compiler.typeof_tfunc(tup_typ)
97+
tup_typ_typ = CC.typeof_tfunc(tup_typ)
9898
if !(newT.val <: Tuple)
99-
tup_typ_typ = Core.Compiler.apply_type_tfunc(Const(NamedTuple{fieldnames(newT.val)}), tup_typ_typ)
99+
tup_typ_typ = CC.apply_type_tfunc(Const(NamedTuple{fieldnames(newT.val)}), tup_typ_typ)
100100
Δbacking = insert_node!(ir, ssa, NewInstruction(Expr(:splatnew, widenconst(tup_typ), Δbacking), tup_typ_typ.val))
101101
end
102-
tangentT = Core.Compiler.apply_type_tfunc(Const(ChainRulesCore.Tangent), newT, tup_typ_typ).val
102+
tangentT = CC.apply_type_tfunc(Const(ChainRulesCore.Tangent), newT, tup_typ_typ).val
103103
Δtangent = insert_node!(ir, ssa, NewInstruction(Expr(:new, tangentT, Δbacking), tangentT))
104104
return Δtangent
105105
else # general frule handling
@@ -124,7 +124,7 @@ function forward_diff_uncached!(ir::IRCode, interp::AbstractInterpreter, irsv::I
124124

125125
# Now do proper type inference with the known arguments
126126
interp′ = disable_forward(interp)
127-
new_frame = Core.Compiler.typeinf_frame(interp′, new_match.method, new_match.spec_types, new_match.sparams, #=run_optimizer=#true)
127+
new_frame = CC.typeinf_frame(interp′, new_match.method, new_match.spec_types, new_match.sparams, #=run_optimizer=#true)
128128

129129
# Create :invoke expression for the newly inferred frule
130130
frule_mi = CC.EscapeAnalysis.analyze_match(new_match, length(args)+2)

src/codegen/reverse.jl

+4-4
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ function diffract_ir!(ir, ci, meth, sparams::Core.SimpleVector, nargs::Int, N::I
414414
end
415415

416416
@static if VERSION v"1.12.0-DEV.173"
417-
debuginfo = Core.Compiler.DebugInfoStream(nothing, opaque_ci.debuginfo, length(code))
417+
debuginfo = CC.DebugInfoStream(nothing, opaque_ci.debuginfo, length(code))
418418
debuginfo.def = :var"N/A"
419419
opaque_ci.debuginfo = Core.DebugInfo(debuginfo, length(code))
420420
else
@@ -501,7 +501,7 @@ function diffract_ir!(ir, ci, meth, sparams::Core.SimpleVector, nargs::Int, N::I
501501
end
502502

503503
@static if VERSION v"1.12.0-DEV.173"
504-
debuginfo = Core.Compiler.DebugInfoStream(nothing, opaque_ci.debuginfo, length(code))
504+
debuginfo = CC.DebugInfoStream(nothing, opaque_ci.debuginfo, length(code))
505505
debuginfo.def = :var"N/A"
506506
opaque_ci.debuginfo = Core.DebugInfo(debuginfo, length(code))
507507
else
@@ -533,7 +533,7 @@ function diffract_ir!(ir, ci, meth, sparams::Core.SimpleVector, nargs::Int, N::I
533533
end
534534

535535
if interp !== nothing
536-
new_argtypes = Any[Const(∂⃖recurse), tuple_tfunc(Core.Compiler.optimizer_lattice(interp), ir.argtypes[1:nfixedargs])]
536+
new_argtypes = Any[Const(∂⃖recurse), tuple_tfunc(CC.optimizer_lattice(interp), ir.argtypes[1:nfixedargs])]
537537
empty!(ir.argtypes)
538538
append!(ir.argtypes, new_argtypes)
539539
end
@@ -672,7 +672,7 @@ function diffract_ir!(ir, ci, meth, sparams::Core.SimpleVector, nargs::Int, N::I
672672
ir = complete(compact)
673673
#@show ir
674674
ir = compact!(ir)
675-
Core.Compiler.verify_ir(ir, true, true)
675+
CC.verify_ir(ir, true, true)
676676

677677
return ir
678678
end

src/debugutils.jl

+15-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Core.Compiler: AbstractInterpreter, CodeInstance, MethodInstance, WorldView, NativeInterpreter
1+
using .CC: AbstractInterpreter, CodeInstance, MethodInstance, WorldView, NativeInterpreter
22
using InteractiveUtils
33

44
function infer_function(interp, tt)
@@ -13,23 +13,23 @@ function infer_function(interp, tt)
1313
mtypes, msp, m = mthds[1]
1414

1515
# Grab the appropriate method instance for these types
16-
mi = Core.Compiler.specialize_method(m, mtypes, msp)
16+
mi = CC.specialize_method(m, mtypes, msp)
1717

1818
# Construct InferenceResult to hold the result,
19-
result = Core.Compiler.InferenceResult(mi)
19+
result = CC.InferenceResult(mi)
2020

2121
# Create an InferenceState to begin inference, give it a world that is always newest
22-
frame = Core.Compiler.InferenceState(result, #=cached=# true, interp)
22+
frame = CC.InferenceState(result, #=cached=# true, interp)
2323

2424
# Run type inference on this frame. Because the interpreter is embedded
2525
# within this InferenceResult, we don't need to pass the interpreter in.
26-
Core.Compiler.typeinf(interp, frame)
26+
CC.typeinf(interp, frame)
2727

2828
# Give the result back
2929
return (mi, result)
3030
end
3131

32-
struct ExtractingInterpreter <: Core.Compiler.AbstractInterpreter
32+
struct ExtractingInterpreter <: CC.AbstractInterpreter
3333
code::Dict{MethodInstance, CodeInstance}
3434
native_interpreter::NativeInterpreter
3535
msgs::Vector{Tuple{MethodInstance, Int, String}}
@@ -43,7 +43,7 @@ ExtractingInterpreter(;optimize=false) = ExtractingInterpreter(
4343
optimize
4444
)
4545

46-
import Core.Compiler: InferenceParams, OptimizationParams, #=get_inference_world,=#
46+
import .CC: InferenceParams, OptimizationParams, #=get_inference_world,=#
4747
get_inference_cache, code_cache,
4848
WorldView, lock_mi_inference, unlock_mi_inference, InferenceState
4949
InferenceParams(ei::ExtractingInterpreter) = InferenceParams(ei.native_interpreter)
@@ -56,18 +56,14 @@ lock_mi_inference(ei::ExtractingInterpreter, mi::MethodInstance) = nothing
5656
unlock_mi_inference(ei::ExtractingInterpreter, mi::MethodInstance) = nothing
5757

5858
code_cache(ei::ExtractingInterpreter) = ei.code
59-
Core.Compiler.get(a::Dict, b, c) = Base.get(a,b,c)
60-
Core.Compiler.get(a::WorldView{<:Dict}, b, c) = Base.get(a.cache,b,c)
61-
Core.Compiler.haskey(a::Dict, b) = Base.haskey(a, b)
62-
Core.Compiler.haskey(a::WorldView{<:Dict}, b) =
63-
Core.Compiler.haskey(a.cache, b)
64-
Core.Compiler.setindex!(a::Dict, b, c) = setindex!(a, b, c)
65-
Core.Compiler.may_optimize(ei::ExtractingInterpreter) = ei.optimize
66-
Core.Compiler.may_compress(ei::ExtractingInterpreter) = false
67-
Core.Compiler.may_discard_trees(ei::ExtractingInterpreter) = false
68-
69-
function Core.Compiler.add_remark!(ei::ExtractingInterpreter, sv::InferenceState, msg)
70-
@show msg
59+
CC.get(a::WorldView{<:Dict}, b, c) = Base.get(a.cache,b,c)
60+
CC.haskey(a::WorldView{<:Dict}, b) =
61+
CC.haskey(a.cache, b)
62+
CC.may_optimize(ei::ExtractingInterpreter) = ei.optimize
63+
CC.may_compress(ei::ExtractingInterpreter) = false
64+
CC.may_discard_trees(ei::ExtractingInterpreter) = false
65+
66+
function CC.add_remark!(ei::ExtractingInterpreter, sv::InferenceState, msg)
7167
push!(ei.msgs, (sv.linfo, sv.currpc, msg))
7268
end
7369

src/extra_rules.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ end
255255

256256
@ChainRules.non_differentiable Base.:(|)(a::Integer, b::Integer)
257257
@ChainRules.non_differentiable Base.throw(err)
258-
@ChainRules.non_differentiable Core.Compiler.return_type(args...)
258+
@ChainRules.non_differentiable CC.return_type(args...)
259259
ChainRulesCore.canonicalize(::NoTangent) = NoTangent()
260260

261261
# Disable thunking at higher order (TODO: These should go into ChainRulesCore)
@@ -294,7 +294,7 @@ Base.:(==)(::ZeroTangent, x::Number) = iszero(x)
294294
Base.hash(x::ZeroTangent, h::UInt64) = hash(0, h)
295295

296296
# should this be in ChainRules/ChainRulesCore?
297-
# Avoid making nested backings, a Tangent is already a valid Tangent for a Tangent,
297+
# Avoid making nested backings, a Tangent is already a valid Tangent for a Tangent,
298298
# or a valid second order Tangent for the primal
299299
function ChainRulesCore.frule((_, ẋ), T::Type{<:Tangent}, x)
300300
::Tangent

src/stage1/compiler_utils.jl

+31-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Utilities that should probably go into CC
2-
using .CC: IRCode, CFG, BasicBlock, BBIdxIter
2+
using .Compiler: IRCode, CFG, BasicBlock, BBIdxIter
33

44
function Base.push!(cfg::CFG, bb::BasicBlock)
55
@assert cfg.blocks[end].stmts.stop+1 == bb.stmts.start
@@ -11,13 +11,37 @@ if VERSION < v"1.11.0-DEV.258"
1111
Base.getindex(ir::IRCode, ssa::SSAValue) = CC.getindex(ir, ssa)
1212
end
1313

14-
if isdefined(CC, :Future)
15-
Base.isready(future::CC.Future) = CC.isready(future)
16-
Base.getindex(future::CC.Future) = CC.getindex(future)
17-
Base.setindex!(future::CC.Future, value) = CC.setindex!(future, value)
18-
end
14+
if VERSION < v"1.12.0-DEV.1268"
15+
if isdefined(CC, :Future)
16+
Base.isready(future::CC.Future) = CC.isready(future)
17+
Base.getindex(future::CC.Future) = CC.getindex(future)
18+
Base.setindex!(future::CC.Future, value) = CC.setindex!(future, value)
19+
end
1920

20-
Base.copy(ir::IRCode) = CC.copy(ir)
21+
Base.iterate(c::IncrementalCompact, args...) = CC.iterate(c, args...)
22+
Base.iterate(p::CC.Pair, args...) = CC.iterate(p, args...)
23+
Base.iterate(urs::CC.UseRefIterator, args...) = CC.iterate(urs, args...)
24+
Base.iterate(x::CC.BBIdxIter, args...) = CC.iterate(x, args...)
25+
Base.getindex(urs::CC.UseRefIterator, args...) = CC.getindex(urs, args...)
26+
Base.getindex(urs::CC.UseRef, args...) = CC.getindex(urs, args...)
27+
Base.getindex(c::CC.IncrementalCompact, args...) = CC.getindex(c, args...)
28+
Base.setindex!(c::CC.IncrementalCompact, args...) = CC.setindex!(c, args...)
29+
Base.setindex!(urs::CC.UseRef, args...) = CC.setindex!(urs, args...)
30+
31+
Base.copy(ir::IRCode) = CC.copy(ir)
32+
33+
CC.BasicBlock(x::UnitRange) =
34+
BasicBlock(StmtRange(first(x), last(x)))
35+
CC.BasicBlock(x::UnitRange, preds::Vector{Int}, succs::Vector{Int}) =
36+
BasicBlock(StmtRange(first(x), last(x)), preds, succs)
37+
Base.length(c::CC.NewNodeStream) = CC.length(c)
38+
Base.setindex!(i::Instruction, args...) = CC.setindex!(i, args...)
39+
Base.size(x::CC.UnitRange) = CC.size(x)
40+
41+
CC.get(a::Dict, b, c) = Base.get(a,b,c)
42+
CC.haskey(a::Dict, b) = Base.haskey(a, b)
43+
CC.setindex!(a::Dict, b, c) = setindex!(a, b, c)
44+
end
2145

2246
CC.NewInstruction(@nospecialize node) =
2347
NewInstruction(node, Any, CC.NoCallInfo(), nothing, CC.IR_FLAG_REFINED)

src/stage1/generated.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ function perform_optic_transform(world::UInt, source::LineNumberNode,
3030
end
3131
match = only(mthds)::Core.MethodMatch
3232

33-
mi = Core.Compiler.specialize_method(match)
34-
ci = Core.Compiler.retrieve_code_info(mi, world)
33+
mi = CC.specialize_method(match)
34+
ci = CC.retrieve_code_info(mi, world)
3535
if ci === nothing
3636
# Failed to retrieve source - likely a generated function that errors.
3737
# To aid the user in debugging, run the original call in the forward pass and if that

src/stage1/hacks.jl

+2-10
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,10 @@
11
# Updated copy of the same code in Base, but with bugs fixed
2-
using Core.Compiler:
2+
using .CC:
33
NewSSAValue, OldSSAValue, StmtRange, BasicBlock,
44
count_added_node!, add_pending!
55

66
# Re-named in https://github.com/JuliaLang/julia/pull/47051
7-
const add! = Core.Compiler.add_inst!
8-
9-
Base.length(c::Core.Compiler.NewNodeStream) = Core.Compiler.length(c)
10-
Base.setindex!(i::Instruction, args...) = Core.Compiler.setindex!(i, args...)
11-
Core.Compiler.BasicBlock(x::UnitRange) =
12-
BasicBlock(StmtRange(first(x), last(x)))
13-
Core.Compiler.BasicBlock(x::UnitRange, preds::Vector{Int}, succs::Vector{Int}) =
14-
BasicBlock(StmtRange(first(x), last(x)), preds, succs)
15-
Base.size(x::Core.Compiler.UnitRange) = Core.Compiler.size(x)
7+
const add! = CC.add_inst!
168

179
function my_insert_node!(compact::IncrementalCompact, before, inst::NewInstruction, attach_after::Bool=false)
1810
@assert inst.effect_free_computed

src/stage1/recurse.jl

+10-20
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
using Core.IR
2-
using Core.Compiler:
2+
using .CC:
33
BasicBlock, CFG, IRCode, IncrementalCompact, Instruction, NewInstruction, NoCallInfo, StmtRange,
44
bbidxiter, cfg_delete_edge!, cfg_insert_edge!, compute_basic_blocks, complete,
55
construct_domtree, construct_ssa!, domsort_ssa!, finish, insert_node!,
66
insert_node_here!, non_dce_finish!, quoted, retrieve_code_info,
77
scan_slot_def_use, userefs, SimpleInferenceLattice
88

99
if VERSION < v"1.11.0-DEV.1351"
10-
using Core.Compiler: effect_free_and_nothrow as removable_if_unused
10+
using .CC: effect_free_and_nothrow as removable_if_unused
1111
else
12-
using Core.Compiler: removable_if_unused
12+
using .CC: removable_if_unused
1313
end
1414

1515
using Base.Meta
@@ -93,7 +93,7 @@ function expand_switch(code::Vector{Any}, bb_ranges::Vector{UnitRange{Int}}, slo
9393
# Now rewrite branch targets back to statement indexing
9494
for i = 1:length(new_code)
9595
stmt = new_code[i]
96-
stmt = Core.Compiler.renumber_ssa!(stmt, renumber)
96+
stmt = CC.renumber_ssa!(stmt, renumber)
9797
stmt = new_to_regular(stmt)
9898
if isa(stmt, GotoNode)
9999
stmt = GotoNode(renumber[first(bb_ranges[stmt.label])].id)
@@ -239,19 +239,9 @@ function split_critical_edges!(ir)
239239
return ir′
240240
end
241241

242-
Base.iterate(c::IncrementalCompact, args...) = Core.Compiler.iterate(c, args...)
243-
Base.iterate(p::Core.Compiler.Pair, args...) = Core.Compiler.iterate(p, args...)
244-
Base.iterate(urs::Core.Compiler.UseRefIterator, args...) = Core.Compiler.iterate(urs, args...)
245-
Base.iterate(x::Core.Compiler.BBIdxIter, args...) = Core.Compiler.iterate(x, args...)
246-
Base.getindex(urs::Core.Compiler.UseRefIterator, args...) = Core.Compiler.getindex(urs, args...)
247-
Base.getindex(urs::Core.Compiler.UseRef, args...) = Core.Compiler.getindex(urs, args...)
248-
Base.getindex(c::Core.Compiler.IncrementalCompact, args...) = Core.Compiler.getindex(c, args...)
249-
Base.setindex!(c::Core.Compiler.IncrementalCompact, args...) = Core.Compiler.setindex!(c, args...)
250-
Base.setindex!(urs::Core.Compiler.UseRef, args...) = Core.Compiler.setindex!(urs, args...)
251-
252-
import Core.Compiler: VarState
242+
import .CC: VarState
253243
function sptypes(sparams)
254-
VarState[Core.Compiler.VarState.(sparams, false)...]
244+
VarState[CC.VarState.(sparams, false)...]
255245
end
256246

257247
function optic_transform(ci::CodeInfo, args...)
@@ -277,12 +267,12 @@ function optic_transform!(ci::CodeInfo, mi::MethodInstance, nargs::Int, N::Int)
277267
argtypes = Any[Any for i = 1:2]
278268
meta = Expr[]
279269
@static if VERSION v"1.12.0-DEV.173"
280-
debuginfo = Core.Compiler.DebugInfoStream(mi, ci.debuginfo, length(code))
281-
stmts = Core.Compiler.InstructionStream(code, type, info, debuginfo.codelocs, flag)
270+
debuginfo = CC.DebugInfoStream(mi, ci.debuginfo, length(code))
271+
stmts = CC.InstructionStream(code, type, info, debuginfo.codelocs, flag)
282272
ir = IRCode(stmts, cfg, debuginfo, argtypes, meta, sptypes(sparams))
283273
else
284274
linetable = Core.LineInfoNode[ci.linetable...]
285-
stmts = Core.Compiler.InstructionStream(code, type, info, ci.codelocs, flag)
275+
stmts = CC.InstructionStream(code, type, info, ci.codelocs, flag)
286276
ir = IRCode(stmts, cfg, linetable, argtypes, meta, sptypes(sparams))
287277
end
288278

@@ -307,7 +297,7 @@ function optic_transform!(ci::CodeInfo, mi::MethodInstance, nargs::Int, N::Int)
307297

308298
ir = diffract_ir!(ir, ci, meth, sparams, nargs, N)
309299

310-
Core.Compiler.replace_code_newstyle!(ci, ir)
300+
CC.replace_code_newstyle!(ci, ir)
311301

312302
ci.ssavaluetypes = length(ci.code)
313303
ci.ssaflags = SSAFlagType[zero(SSAFlagType) for i=1:length(ci.code)]

src/stage1/recurse_fwd.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ end
8181
function fwd_transform!(ci::CodeInfo, mi::MethodInstance, nargs::Int, N::Int, E)
8282
new_code = Any[]
8383
@static if VERSION v"1.12.0-DEV.173"
84-
debuginfo = Core.Compiler.DebugInfoStream(mi, ci.debuginfo, length(ci.code))
84+
debuginfo = CC.DebugInfoStream(mi, ci.debuginfo, length(ci.code))
8585
new_codelocs = Int32[]
8686
else
8787
new_codelocs = Any[]
@@ -243,8 +243,8 @@ function perform_fwd_transform(world::UInt, source::LineNumberNode,
243243
end
244244
match = only(mthds)::Core.MethodMatch
245245

246-
mi = Core.Compiler.specialize_method(match)
247-
ci = Core.Compiler.retrieve_code_info(mi, world)
246+
mi = CC.specialize_method(match)
247+
ci = CC.retrieve_code_info(mi, world)
248248

249249
return fwd_transform(ci, mi, length(args)-1, N, E)
250250
end

0 commit comments

Comments
 (0)