Skip to content

Inversion of ComplexF32 numbers uses Float64 numbers and fails to compile #871

Description

@phaerrax

Hello! Working with Metal.jl I have encountered the following issue. When computing the inverse of ComplexF32 numbers, some Float64 numbers seem to sneak in and cause Metal.jl to throw an error.

Here's a minimal example:

using Metal

function mwe(T)
    d = mtl(rand(T, 2, 2))
    return inv.(d)
end

If T = Float32, everything works fine. If T = ComplexF32 instead, I get the following error:

julia> mwe(ComplexF32)
ERROR: InvalidIRError: compiling MethodInstance for (::Metal.var"#broadcast_2d#_copyto!##2")(::MtlDeviceMatrix{ComplexF32, 1}, ::Base.Broadcast.Broadcasted{Metal.MtlArrayStyle{…}, Tuple{…}, typeof(inv), Tuple{…}}) resulted in invalid LLVM IR
Reason: unsupported use of double value
Stacktrace:
  [1] Float64
    @ ./float.jl:345
  [2] convert
    @ ./number.jl:7
  [3] Complex
    @ ./complex.jl:14
  [4] Complex
    @ ./complex.jl:43
  [5] convert
    @ ./number.jl:7
  [6] widen
    @ ./operators.jl:946
  [7] inv
    @ ./complex.jl:474
  [8] _broadcast_getindex_evalf
    @ ./broadcast.jl:699
  [9] _broadcast_getindex
    @ ./broadcast.jl:672
 [10] _getindex
    @ ./broadcast.jl:620
 [11] getindex
    @ ./broadcast.jl:616
 [12] broadcast_2d
    @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
  [1] Float64
    @ ./float.jl:345
  [2] convert
    @ ./number.jl:7
  [3] Complex
    @ ./complex.jl:14
  [4] Complex
    @ ./complex.jl:43
  [5] convert
    @ ./number.jl:7
  [6] widen
    @ ./operators.jl:946
  [7] inv
    @ ./complex.jl:474
  [8] _broadcast_getindex_evalf
    @ ./broadcast.jl:699
  [9] _broadcast_getindex
    @ ./broadcast.jl:672
 [10] _getindex
    @ ./broadcast.jl:620
 [11] getindex
    @ ./broadcast.jl:616
 [12] broadcast_2d
    @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] abs
   @ ./float.jl:699
 [2] isinf
   @ ./float.jl:724
 [3] inv
   @ ./complex.jl:475
 [4] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [5] _broadcast_getindex
   @ ./broadcast.jl:672
 [6] _getindex
   @ ./broadcast.jl:620
 [7] getindex
   @ ./broadcast.jl:616
 [8] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] isinf
   @ ./float.jl:724
 [2] inv
   @ ./complex.jl:475
 [3] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [4] _broadcast_getindex
   @ ./broadcast.jl:672
 [5] _getindex
   @ ./broadcast.jl:620
 [6] getindex
   @ ./broadcast.jl:616
 [7] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] abs
   @ ./float.jl:699
 [2] isinf
   @ ./float.jl:724
 [3] inv
   @ ./complex.jl:475
 [4] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [5] _broadcast_getindex
   @ ./broadcast.jl:672
 [6] _getindex
   @ ./broadcast.jl:620
 [7] getindex
   @ ./broadcast.jl:616
 [8] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] isinf
   @ ./float.jl:724
 [2] inv
   @ ./complex.jl:475
 [3] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [4] _broadcast_getindex
   @ ./broadcast.jl:672
 [5] _getindex
   @ ./broadcast.jl:620
 [6] getindex
   @ ./broadcast.jl:616
 [7] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] muladd
   @ ./float.jl:500
 [2] inv
   @ ./complex.jl:476
 [3] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [4] _broadcast_getindex
   @ ./broadcast.jl:672
 [5] _getindex
   @ ./broadcast.jl:620
 [6] getindex
   @ ./broadcast.jl:616
 [7] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] *
   @ ./float.jl:497
 [2] literal_pow
   @ ./intfuncs.jl:437
 [3] inv
   @ ./complex.jl:476
 [4] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [5] _broadcast_getindex
   @ ./broadcast.jl:672
 [6] _getindex
   @ ./broadcast.jl:620
 [7] getindex
   @ ./broadcast.jl:616
 [8] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] muladd
   @ ./float.jl:500
 [2] inv
   @ ./complex.jl:476
 [3] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [4] _broadcast_getindex
   @ ./broadcast.jl:672
 [5] _getindex
   @ ./broadcast.jl:620
 [6] getindex
   @ ./broadcast.jl:616
 [7] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] /
   @ ./float.jl:498
 [2] inv
   @ ./number.jl:255
 [3] inv
   @ ./complex.jl:476
 [4] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [5] _broadcast_getindex
   @ ./broadcast.jl:672
 [6] _getindex
   @ ./broadcast.jl:620
 [7] getindex
   @ ./broadcast.jl:616
 [8] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] -
   @ ./float.jl:493
 [2] inv
   @ ./complex.jl:477
 [3] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [4] _broadcast_getindex
   @ ./broadcast.jl:672
 [5] _getindex
   @ ./broadcast.jl:620
 [6] getindex
   @ ./broadcast.jl:616
 [7] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] *
   @ ./float.jl:497
 [2] inv
   @ ./complex.jl:477
 [3] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [4] _broadcast_getindex
   @ ./broadcast.jl:672
 [5] _getindex
   @ ./broadcast.jl:620
 [6] getindex
   @ ./broadcast.jl:616
 [7] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
  [1] Float32
    @ ./float.jl:342
  [2] convert
    @ ./number.jl:7
  [3] Complex
    @ ./complex.jl:14
  [4] Complex
    @ ./complex.jl:43
  [5] convert
    @ ./number.jl:7
  [6] oftype
    @ ./essentials.jl:666
  [7] inv
    @ ./complex.jl:477
  [8] _broadcast_getindex_evalf
    @ ./broadcast.jl:699
  [9] _broadcast_getindex
    @ ./broadcast.jl:672
 [10] _getindex
    @ ./broadcast.jl:620
 [11] getindex
    @ ./broadcast.jl:616
 [12] broadcast_2d
    @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
 [1] *
   @ ./float.jl:497
 [2] inv
   @ ./complex.jl:477
 [3] _broadcast_getindex_evalf
   @ ./broadcast.jl:699
 [4] _broadcast_getindex
   @ ./broadcast.jl:672
 [5] _getindex
   @ ./broadcast.jl:620
 [6] getindex
   @ ./broadcast.jl:616
 [7] broadcast_2d
   @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Reason: unsupported use of double value
Stacktrace:
  [1] Float32
    @ ./float.jl:342
  [2] convert
    @ ./number.jl:7
  [3] Complex
    @ ./complex.jl:14
  [4] Complex
    @ ./complex.jl:43
  [5] convert
    @ ./number.jl:7
  [6] oftype
    @ ./essentials.jl:666
  [7] inv
    @ ./complex.jl:477
  [8] _broadcast_getindex_evalf
    @ ./broadcast.jl:699
  [9] _broadcast_getindex
    @ ./broadcast.jl:672
 [10] _getindex
    @ ./broadcast.jl:620
 [11] getindex
    @ ./broadcast.jl:616
 [12] broadcast_2d
    @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:119
Hint: catch this exception as `err` and call `code_typed(err; interactive = true)` to introspect the erroneous code with Cthulhu.jl
Stacktrace:
  [1] check_ir(job::GPUCompiler.CompilerJob{GPUCompiler.MetalCompilerTarget, Metal.MetalCompilerParams}, args::LLVM.Module)
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/validation.jl:170
  [2] emit_llvm(job::GPUCompiler.CompilerJob; kwargs::@Kwargs{})
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:455
  [3] emit_llvm(job::GPUCompiler.CompilerJob)
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:200
  [4] compile_unhooked(output::Symbol, job::GPUCompiler.CompilerJob; kwargs::@Kwargs{})
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:101
  [5] compile_unhooked
    @ ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:80 [inlined]
  [6] #compile#118
    @ ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:67 [inlined]
  [7] compile(target::Symbol, job::GPUCompiler.CompilerJob)
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:55
  [8] #invoke_frozen#19
    @ ~/.julia/packages/Metal/TF981/src/initialization.jl:15 [inlined]
  [9] invoke_frozen
    @ ~/.julia/packages/Metal/TF981/src/initialization.jl:13 [inlined]
 [10] macro expansion
    @ ~/.julia/packages/Metal/TF981/src/compiler/compilation.jl:436 [inlined]
 [11] macro expansion
    @ ~/.julia/packages/ObjectiveC/ectoz/src/os.jl:264 [inlined]
 [12] (::Metal.var"#compile##0#compile##1"{GPUCompiler.CompilerJob{GPUCompiler.MetalCompilerTarget, Metal.MetalCompilerParams}})(ctx::LLVM.Context)
    @ Metal ~/.julia/packages/Metal/TF981/src/compiler/compilation.jl:435
 [13] JuliaContext(f::Metal.var"#compile##0#compile##1"{GPUCompiler.CompilerJob{GPUCompiler.MetalCompilerTarget, Metal.MetalCompilerParams}}; kwargs::@Kwargs{})
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:34
 [14] JuliaContext(f::Function)
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/driver.jl:25
 [15] compile(job::GPUCompiler.CompilerJob)
    @ Metal ~/.julia/packages/Metal/TF981/src/compiler/compilation.jl:434
 [16] actual_compilation(cache::Dict{…}, src::Core.MethodInstance, world::UInt64, cfg::GPUCompiler.CompilerConfig{…}, compiler::typeof(Metal.compile), linker::typeof(Metal.link))
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/execution.jl:245
 [17] cached_compilation(cache::Dict{…}, src::Core.MethodInstance, cfg::GPUCompiler.CompilerConfig{…}, compiler::Function, linker::Function)
    @ GPUCompiler ~/.julia/packages/GPUCompiler/QgckP/src/execution.jl:159
 [18] macro expansion
    @ ~/.julia/packages/Metal/TF981/src/compiler/execution.jl:199 [inlined]
 [19] macro expansion
    @ ./lock.jl:376 [inlined]
 [20] mtlfunction(f::Metal.var"#broadcast_2d#_copyto!##2", tt::Type{Tuple{MtlDeviceMatrix{…}, Base.Broadcast.Broadcasted{…}}}; name::Nothing, kwargs::@Kwargs{})
    @ Metal ~/.julia/packages/Metal/TF981/src/compiler/execution.jl:194
 [21] mtlfunction
    @ ~/.julia/packages/Metal/TF981/src/compiler/execution.jl:192 [inlined]
 [22] macro expansion
    @ ~/.julia/packages/Metal/TF981/src/compiler/execution.jl:89 [inlined]
 [23] _copyto!
    @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:128 [inlined]
 [24] copyto!
    @ ~/.julia/packages/Metal/TF981/src/broadcast.jl:52 [inlined]
 [25] copy
    @ ~/.julia/packages/GPUArrays/VNJ6B/src/host/broadcast.jl:34 [inlined]
 [26] materialize(bc::Base.Broadcast.Broadcasted{Metal.MtlArrayStyle{2, Metal.PrivateStorage}, Nothing, typeof(inv), Tuple{MtlMatrix{ComplexF32, Metal.PrivateStorage}}})
    @ Base.Broadcast ./broadcast.jl:894
 [27] mwe(T::Type)
    @ Main ~/Projects/mwe.jl:4
 [28] top-level scope
    @ REPL[3]:1
 [29] top-level scope
    @ ~/.julia/packages/Metal/TF981/src/initialization.jl:110
Some type information was truncated. Use `show(err)` to see complete types.

The stacktrace is huge, but “Reason: unsupported use of double value” appears frequently. In this Julia Discourse thread it was suggested that widen is the culprit.
Adding @fastmath before inv.(d) in the function above makes mwe work, but it doesn’t seem like a proper solution. I won’t always be able to do this, for example if inv is called inside a package function.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions