TensorCast.jl icon indicating copy to clipboard operation
TensorCast.jl copied to clipboard

World Age Issues with TensorCast calls from pyJulia

Open andrewkhardy opened this issue 3 years ago • 3 comments

I am getting a world age bug when running TensorCast in JuliaPy, but not when using it normally.

If I run an example function such as

function testfunc()
    V = [10,20,30]
    M = collect(reshape(1:12, 3,4))
    @cast A[j,i] := M[i,j] + 10 * V[i]
    return A
end

it works when I call it in Julia via

A = testfunc()

However, when I run the Python script

from julia.api import Julia
jl = Julia(compiled_modules=False)
from julia import Main
Main.include("testfunction.jl")
from julia.Main import testfunc

A = testfunc()

I get the error

<PyCall.jlwrap (in a Julia function called from Python)
JULIA: MethodError: no method matching _trex(::Symbol, ::Type{Matrix{Int64}}, ::Tuple{Int64, Int64})
The applicable method may be too new: running in world age 32486, while current world is 38140.
Closest candidates are:
  _trex(::Any, ::Any, ::Any) at /home/andrewhardy/.julia/packages/TransmuteDims/mGkQB/src/TransmuteDims.jl:372 (method too new to be called from this world context.)

which only occurs for the @cast call. What can I do?

andrewkhardy avatar Aug 10 '22 15:08 andrewkhardy

I have never used pyJulia, but did briefly manage to get this error directly from the repl:

julia> TensorCast.transmute(rand(2,2), Val((2, 1)))
ERROR: MethodError: no method matching _trex(::Symbol, ::Type{Matrix{Float64}}, ::Tuple{Int64, Int64})
The applicable method may be too new: running in world age 45668, while current world is 47824.

What TensorCast.jl is doing here is very simple, the macro expands to this:

julia> @pretty @cast A[j,i] := M[i,j] + 10 * V[i]
begin
    @boundscheck ndims(M) == 2 || throw(ArgumentError("expected a 2-tensor M[i, j]"))
    @boundscheck axes(M, 1) == axes(V, 1) || throw(DimensionMismatch("range of index i must agree"))
    @boundscheck V isa Tuple || (ndims(V) == 1 || throw(ArgumentError("expected a vector or tuple V[i]")))
    local guineafowl = transmute(M, Val((2, 1)))
    local giraffe = transmute(V, Val((nothing, 1)))
    A = @__dot__(guineafowl + 10giraffe)
end

But transmute is a generalised version of permutedims, which has some @generated methods, and these are (I presume) what's causing the world age problem. But why, I'm not sure. I think such things can happen if code is updated after loading, or something... am not so sure how to track down what's gone wrong, nor to fix it.

mcabbott avatar Aug 11 '22 03:08 mcabbott

For what it is worth @reduce does not throw these errors. Does that have any generated methods?

andrewkhardy avatar Aug 11 '22 15:08 andrewkhardy

Depends on the expression, for both. Any transmute(M, ::Val) call is generated, I think, and @pretty will show you what the macro calls.

mcabbott avatar Aug 24 '22 03:08 mcabbott