# Inverting ComplexF32 with Metal.jl throws an error

**URL:** <https://discourse.julialang.org/t/inverting-complexf32-with-metal-jl-throws-an-error/137991>\
**Category:** General Usage\
**Tags:** gpu, metaljl\
**Created:** [July 7, 2026, 9:58pm UTC](https://discourse.julialang.org/t/inverting-complexf32-with-metal-jl-throws-an-error/137991 "2026-07-07T21:58:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![phx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/phx/32/219940_2.png) [@phx](https://discourse.julialang.org/u/phx)\
**Post date:** [July 7, 2026, 9:58pm UTC](https://discourse.julialang.org/t/inverting-complexf32-with-metal-jl-throws-an-error/137991/1 "2026-07-07T21:58:41Z")

</div>

Hi everyone! I’m working with Metal.jl on an Apple Silicon GPU and I’ve 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:

```julia
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-auto
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. I guess a double-precision float, which I know Metal.jl can’t use, is created somewhere along the way. Is this a solvable issue or a bug?

---

<div class="post-metadata">

**Author:** ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)\
**Post date:** [July 7, 2026, 10:10pm UTC](https://discourse.julialang.org/t/inverting-complexf32-with-metal-jl-throws-an-error/137991/2 "2026-07-07T22:10:51Z")

</div>

The explanation of the error is right there in the stacktrace: `inv` calls `widen`:

> <https://github.com/JuliaLang/julia/blob/6fe1d511056d3850d8f027c386dec8674d0bc4db/base/complex.jl#L466-L471>

Metal.jl would need to overly that method with a different one which doesn’t involve going through double precision.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 7, 2026, 11:50pm UTC](https://discourse.julialang.org/t/inverting-complexf32-with-metal-jl-throws-an-error/137991/3 "2026-07-07T23:50:02Z")

</div>

> [@giordano](#):
>
> [Metal.jl](https://juliaregistries.github.io/General/packages/redirect_to_repo/Metal) would need to overly that method with a different one which doesn’t involve going through double precision.

You can just use `@fastmath inv.(d)` to avoid widening (sacrificing a little accuracy).
