[ANN] Initial release of new ITensor GPU backends

Hey Matt, I just tried to run this but got the following error, any suggestions for what’s up?
There seems to be some conflict between Metal and NDTensors, although I have just installed fresh versions of both.
Running Pkg.instantiate() as it suggests lets me get past the import error, but then I get another error when I get to the final tensor contraction.

(@v1.8) pkg> status
Status `~/.julia/environments/v1.8/Project.toml`
  [9e7568c4] Basinhopping v0.1.0
  [6e4b80f9] BenchmarkTools v1.3.2
  [31c24e10] Distributions v0.25.103
  [b7d42ee7] Einsum v0.4.1
  [4c0ca9eb] Gtk v1.3.0
⌅ [f67ccb44] HDF5 v0.16.16
  [7073ff75] IJulia v1.24.2
  [9136182c] ITensors v0.3.51
  [4138dd39] JLD v0.13.3
  [033835bb] JLD2 v0.4.38
  [0b1a1467] KrylovKit v0.6.0
  [dde4c033] Metal v0.5.1
  [23ae76d9] NDTensors v0.2.20
  [15e1cf62] NPZ v0.4.3
  [429524aa] Optim v1.7.8
  [77e91f04] OptimKit v0.3.1
  [91a5bcdd] Plots v1.39.0
  [c46f51b8] ProfileView v1.7.2
  [438e738f] PyCall v1.96.2
  [6c8a4c8a] RelevanceStacktrace v0.1.8
  [90137ffa] StaticArrays v1.6.5
⌃ [2913bbd2] StatsBase v0.33.21
  [fd094767] Suppressor v0.2.6
  [07d1fe3e] TensorKit v0.12.0
  [6aa20fa7] TensorOperations v4.0.7
  [770da0de] UpdateJulia v0.4.2
  [e88e6eb3] Zygote v0.6.67
  [37e2e46d] LinearAlgebra
  [56ddb016] Logging
  [de0858da] Printf
Info Packages marked with ⌃ and ⌅ have new versions available, but those with ⌅ are restricted by compatibility constraints from upgrading. To see why use `status --outdated`

julia> using ITensors

julia> using Metal
┌ Warning: Error requiring `Metal` from `NDTensors`
│   exception =
│    LoadError: ArgumentError: Package NDTensors does not have Metal in its dependencies:
│    - You may have a partially installed environment. Try `Pkg.instantiate()`
│      to ensure all packages in the environment are installed.
│    - Or, if you have NDTensors checked out for development and have
│      added Metal as a dependency but haven't updated your primary
│      environment's manifest file, try `Pkg.resolve()`.
│    - Otherwise you may need to report an issue with NDTensors
│    Stacktrace:
│      [1] macro expansion
│        @ ./loading.jl:1167 [inlined]
│      [2] macro expansion
│        @ ./lock.jl:223 [inlined]
│      [3] require(into::Module, mod::Symbol)
│        @ Base ./loading.jl:1144
│      [4] include(mod::Module, _path::String)
│        @ Base ./Base.jl:419
│      [5] include(x::String)
│        @ NDTensors.NDTensorsMetalExt ~/.julia/packages/NDTensors/Zu1iT/ext/NDTensorsMetalExt/NDTensorsMetalExt.jl:1
│      [6] top-level scope
│        @ ~/.julia/packages/NDTensors/Zu1iT/ext/NDTensorsMetalExt/NDTensorsMetalExt.jl:16
│      [7] include(mod::Module, _path::String)
│        @ Base ./Base.jl:419
│      [8] include(x::String)
│        @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/NDTensors.jl:1
│      [9] macro expansion
│        @ ~/.julia/packages/Requires/Z8rfN/src/Requires.jl:40 [inlined]
│     [10] top-level scope
│        @ ~/.julia/packages/NDTensors/Zu1iT/src/NDTensors.jl:335
│     [11] eval
│        @ ./boot.jl:368 [inlined]
│     [12] eval
│        @ ~/.julia/packages/NDTensors/Zu1iT/src/NDTensors.jl:1 [inlined]
│     [13] (::NDTensors.var"#259#271")()
│        @ NDTensors ~/.julia/packages/Requires/Z8rfN/src/require.jl:101
│     [14] macro expansion
│        @ ./timing.jl:382 [inlined]
│     [15] err(f::Any, listener::Module, modname::String, file::String, line::Any)
│        @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:47
│     [16] (::NDTensors.var"#258#270")()
│        @ NDTensors ~/.julia/packages/Requires/Z8rfN/src/require.jl:100
│     [17] withpath(f::Any, path::String)
│        @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:37
│     [18] (::NDTensors.var"#257#269")()
│        @ NDTensors ~/.julia/packages/Requires/Z8rfN/src/require.jl:99
│     [19] #invokelatest#2
│        @ ./essentials.jl:729 [inlined]
│     [20] invokelatest
│        @ ./essentials.jl:726 [inlined]
│     [21] foreach(f::typeof(Base.invokelatest), itr::Vector{Function})
│        @ Base ./abstractarray.jl:2774
│     [22] loadpkg(pkg::Base.PkgId)
│        @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:27
│     [23] #invokelatest#2
│        @ ./essentials.jl:729 [inlined]
│     [24] invokelatest
│        @ ./essentials.jl:726 [inlined]
│     [25] run_package_callbacks(modkey::Base.PkgId)
│        @ Base ./loading.jl:869
│     [26] _require_prelocked(uuidkey::Base.PkgId)
│        @ Base ./loading.jl:1206
│     [27] macro expansion
│        @ ./loading.jl:1180 [inlined]
│     [28] macro expansion
│        @ ./lock.jl:223 [inlined]
│     [29] require(into::Module, mod::Symbol)
│        @ Base ./loading.jl:1144
│     [30] eval
│        @ ./boot.jl:368 [inlined]
│     [31] eval_user_input(ast::Any, backend::REPL.REPLBackend)
│        @ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:151
│     [32] repl_backend_loop(backend::REPL.REPLBackend)
│        @ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:247
│     [33] start_repl_backend(backend::REPL.REPLBackend, consumer::Any)
│        @ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:232
│     [34] run_repl(repl::REPL.AbstractREPL, consumer::Any; backend_on_current_task::Bool)
│        @ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:369
│     [35] run_repl(repl::REPL.AbstractREPL, consumer::Any)
│        @ REPL /Applications/Julia-1.8.app/Contents/Resources/julia/share/julia/stdlib/v1.8/REPL/src/REPL.jl:355
│     [36] (::Base.var"#967#969"{Bool, Bool, Bool})(REPL::Module)
│        @ Base ./client.jl:419
│     [37] #invokelatest#2
│        @ ./essentials.jl:729 [inlined]
│     [38] invokelatest
│        @ ./essentials.jl:726 [inlined]
│     [39] run_main_repl(interactive::Bool, quiet::Bool, banner::Bool, history_file::Bool, color_set::Bool)
│        @ Base ./client.jl:404
│     [40] exec_options(opts::Base.JLOptions)
│        @ Base ./client.jl:318
│     [41] _start()
│        @ Base ./client.jl:522
│    in expression starting at /Users/joe/.julia/packages/NDTensors/Zu1iT/ext/NDTensorsMetalExt/imports.jl:5
│    in expression starting at /Users/joe/.julia/packages/NDTensors/Zu1iT/ext/NDTensorsMetalExt/NDTensorsMetalExt.jl:1
└ @ Requires ~/.julia/packages/Requires/Z8rfN/src/require.jl:51

julia> using Pkg

julia> Pkg.instantiate()

julia> using Metal

julia> i = Index([QN(0) => 1000, QN(1) => 1000]);

julia> A = randomITensor(i', dag(i));

julia> using BenchmarkTools

julia> @btime $(A)' * $(A);
  37.977 ms (66 allocations: 30.53 MiB)

julia> @btime $(mtl(A))' * $(mtl(A));
ERROR: Setting the type parameter of the type `MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}` at position `NDTensors.SetParameters.Position{1}()` to `Float32` is not currently defined. Either that type parameter position doesn't exist in the type, or `set_parameter` has not been overloaded for this type.
Stacktrace:
  [1] error(s::String)
    @ Base ./error.jl:35
  [2] set_parameter(type::Type, position::NDTensors.SetParameters.Position{1}, parameter::Type)
    @ NDTensors.SetParameters ~/.julia/packages/NDTensors/Zu1iT/src/SetParameters/src/interface.jl:10
  [3] set_parameters(type::Type, position::NDTensors.SetParameters.Position{1}, parameter::Type)
    @ NDTensors.SetParameters ~/.julia/packages/NDTensors/Zu1iT/src/SetParameters/src/set_parameters.jl:20
  [4] set_eltype(arraytype::Type{MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}}, eltype::Type)
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/abstractarray/set_types.jl:8
  [5] similartype(::Type{SimpleTraits.Not{NDTensors.Unwrap.IsWrappedArray{MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}}}}, arraytype::Type{MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}}, eltype::Type)
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/abstractarray/similar.jl:107
  [6] similartype
    @ ~/.julia/packages/SimpleTraits/l1ZsK/src/SimpleTraits.jl:331 [inlined]
  [7] similartype(arraytype::Type{MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}})
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/abstractarray/similar.jl:121
  [8] similartype(storagetype::Type{NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}, dims::Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}})
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/tensorstorage/similar.jl:75
  [9] similartype(tensortype::Type{NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}}, dims::Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}})
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/tensor/similar.jl:67
 [10] contraction_output_type(tensortype1::Type{NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}}, tensortype2::Type{NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}}, inds::Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}})
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/tensoralgebra/generic_tensor_operations.jl:38
 [11] contraction_output(tensor1::NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}, labelstensor1::Tuple{Int64, Int64}, tensor2::NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}, labelstensor2::Tuple{Int64, Int64}, labelsR::Tuple{Int64, Int64})
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/blocksparse/contract.jl:26
 [12] contract(tensor1::NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}, labelstensor1::Tuple{Int64, Int64}, tensor2::NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}, labelstensor2::Tuple{Int64, Int64}, labelsR::Tuple{Int64, Int64}) (repeats 2 times)
    @ NDTensors ~/.julia/packages/NDTensors/Zu1iT/src/blocksparse/contract.jl:8
 [13] _contract(A::NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}}, B::NDTensors.BlockSparseTensor{Float32, 2, Tuple{Index{Vector{Pair{QN, Int64}}}, Index{Vector{Pair{QN, Int64}}}}, NDTensors.BlockSparse{Float32, MtlVector{Float32, Metal.MTL.MTLResourceStorageModePrivate}, 2}})
    @ ITensors ~/.julia/packages/ITensors/YVElE/src/tensor_operations/tensor_algebra.jl:3
 [14] _contract(A::ITensor, B::ITensor)
    @ ITensors ~/.julia/packages/ITensors/YVElE/src/tensor_operations/tensor_algebra.jl:9
 [15] contract(A::ITensor, B::ITensor)
    @ ITensors ~/.julia/packages/ITensors/YVElE/src/tensor_operations/tensor_algebra.jl:104
 [16] *
    @ ~/.julia/packages/ITensors/YVElE/src/tensor_operations/tensor_algebra.jl:91 [inlined]
 [17] var"##core#342"(340::ITensor, 341::ITensor)
    @ Main ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:489
 [18] var"##sample#343"(::Tuple{ITensor, ITensor}, __params::BenchmarkTools.Parameters)
    @ Main ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:495
 [19] _run(b::BenchmarkTools.Benchmark, p::BenchmarkTools.Parameters; verbose::Bool, pad::String, kwargs::Base.Pairs{Symbol, Integer, NTuple{4, Symbol}, NamedTuple{(:samples, :evals, :gctrial, :gcsample), Tuple{Int64, Int64, Bool, Bool}}})
    @ BenchmarkTools ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:99
 [20] #invokelatest#2
    @ ./essentials.jl:731 [inlined]
 [21] #run_result#45
    @ ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:34 [inlined]
 [22] run(b::BenchmarkTools.Benchmark, p::BenchmarkTools.Parameters; progressid::Nothing, nleaves::Float64, ndone::Float64, kwargs::Base.Pairs{Symbol, Integer, NTuple{5, Symbol}, NamedTuple{(:verbose, :samples, :evals, :gctrial, :gcsample), Tuple{Bool, Int64, Int64, Bool, Bool}}})
    @ BenchmarkTools ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:117
 [23] #warmup#54
    @ ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:169 [inlined]
 [24] warmup(item::BenchmarkTools.Benchmark)
    @ BenchmarkTools ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:168
 [25] top-level scope
    @ ~/.julia/packages/BenchmarkTools/0owsb/src/execution.jl:575
 [26] top-level scope
    @ ~/.julia/packages/Metal/lnkVP/src/initialization.jl:57

julia>