diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 820641b..8f72f97 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -23,7 +23,7 @@ jobs: fail-fast: false matrix: version: - - '1.9' + - '1.10' - 'lts' - '1' os: @@ -39,6 +39,13 @@ jobs: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - uses: julia-actions/cache@v2 + - name: Add Julia Registries + run: | + julia -e ' + using Pkg + Pkg.Registry.add( + RegistrySpec(url = "https://github.com/tensor4all/T4ARegistry.git") + )' - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-runtest@v1 continue-on-error: ${{ matrix.version == 'nightly' }} @@ -52,6 +59,13 @@ jobs: - uses: julia-actions/setup-julia@v2 with: version: '1' + - name: Add Julia Registries + run: | + julia -e ' + using Pkg + Pkg.Registry.add( + RegistrySpec(url = "https://github.com/tensor4all/T4ARegistry.git") + )' - uses: julia-actions/julia-buildpkg@v1 - uses: julia-actions/julia-docdeploy@v1 env: diff --git a/Project.toml b/Project.toml index de60a68..c399aea 100644 --- a/Project.toml +++ b/Project.toml @@ -13,9 +13,9 @@ T4ATensorCI = "14428447-6903-48c7-83df-f2cb08af9918" [compat] MPI = "0.20.22" MPIPreferences = "0.1.11" -Random = "1.10.0" -T4ATensorCI = "0.11" -julia = "1.6" +Random = "1" +T4ATensorCI = "0.12" +julia = "1.10" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" diff --git a/src/contraction.jl b/src/contraction.jl index 025f24f..a7e1c5b 100644 --- a/src/contraction.jl +++ b/src/contraction.jl @@ -1068,6 +1068,7 @@ function contract_distr_fit( for sweep in 1:nsweeps tot_disc = 0.0 + disc = 0.0 # Initialize disc to avoid undefined variable if sweep % 2 == juliarank % 2 direction = :forward @@ -1112,17 +1113,17 @@ function contract_distr_fit( disc = updatecore!(A, B, C, last_site, Ls, Rs; method, tolerance=tolerance/((n-1)*nprocs), maxbonddim, random_update) - Ci = TCI.sitetensor(C, last_site) - Yci = inversesingularvalue(C, last_site) - Cip1 = TCI.sitetensor(C, last_site+1) + Ci_local = TCI.sitetensor(C, last_site) + Yci_local = inversesingularvalue(C, last_site) + Cip1_local = TCI.sitetensor(C, last_site+1) - MPI.Send(collect(size(Ci)), comm; dest=mpirank+1, tag=3*juliarank) - MPI.Send(collect(size(Yci)), comm; dest=mpirank+1, tag=3*juliarank+1) - MPI.Send(collect(size(Cip1)), comm; dest=mpirank+1, tag=3*juliarank+2) + MPI.Send(collect(size(Ci_local)), comm; dest=mpirank+1, tag=3*juliarank) + MPI.Send(collect(size(Yci_local)), comm; dest=mpirank+1, tag=3*juliarank+1) + MPI.Send(collect(size(Cip1_local)), comm; dest=mpirank+1, tag=3*juliarank+2) - MPI.Send(Ci, comm; dest=mpirank+1, tag=3*juliarank) - MPI.Send(Yci, comm; dest=mpirank+1, tag=3*juliarank+1) - MPI.Send(Cip1, comm; dest=mpirank+1, tag=3*juliarank+2) + MPI.Send(Ci_local, comm; dest=mpirank+1, tag=3*juliarank) + MPI.Send(Yci_local, comm; dest=mpirank+1, tag=3*juliarank+1) + MPI.Send(Cip1_local, comm; dest=mpirank+1, tag=3*juliarank+2) rightenvironment!(Rs, A, B, C, last_site+1; random_env, p) end @@ -1150,22 +1151,27 @@ function contract_distr_fit( MPI.Recv!(sizes1, comm; source=mpirank-1, tag=3*(juliarank-1)+1) MPI.Recv!(sizes2, comm; source=mpirank-1, tag=3*(juliarank-1)+2) - Ci = Array{ValueType,4}(undef, sizes...) - Yci = Array{Float64,2}(undef, sizes1...) - Cip1 = Array{ValueType,4}(undef, sizes2...) + Ci_local = Array{ValueType,4}(undef, sizes...) + Yci_local = Array{Float64,2}(undef, sizes1...) + Cip1_local = Array{ValueType,4}(undef, sizes2...) - MPI.Recv!(Ci, comm; source=mpirank-1, tag=3*(juliarank-1)) - MPI.Recv!(Yci, comm; source=mpirank-1, tag=3*(juliarank-1)+1) - MPI.Recv!(Cip1, comm; source=mpirank-1, tag=3*(juliarank-1)+2) + MPI.Recv!(Ci_local, comm; source=mpirank-1, tag=3*(juliarank-1)) + MPI.Recv!(Yci_local, comm; source=mpirank-1, tag=3*(juliarank-1)+1) + MPI.Recv!(Cip1_local, comm; source=mpirank-1, tag=3*(juliarank-1)+2) - settwositetensors!(C, first_site-1, Ci, Yci, Cip1) + settwositetensors!(C, first_site-1, Ci_local, Yci_local, Cip1_local) leftenvironment!(Ls, A, B, C, first_site-1; random_env, p) end end end - - tot_disc += disc + # disc is already defined in the if/else blocks above and accumulated in tot_disc + # If MPI.Initialized() block executed, disc may have been redefined for boundary updates + # Add the boundary disc if it was computed + if MPI.Initialized() && ((juliarank % 2 == sweep % 2 && juliarank != nprocs) || (juliarank % 2 != sweep % 2 && juliarank != 1)) + # disc was redefined in MPI block for boundary update, add it + tot_disc += disc + end converged = tot_disc < tolerance global_converged = MPI.Allreduce(converged, MPI.LAND, comm) @@ -1398,6 +1404,7 @@ function contract_distr_fit( for sweep in 1:nsweeps tot_disc = 0.0 + disc = 0.0 # Initialize disc to avoid undefined variable time_update = time_ns() if sweep % 2 == juliarank % 2 @@ -1447,16 +1454,16 @@ function contract_distr_fit( disc = updatecore!(A, B, C, last_site, Ls, Rs; method, tolerance=tolerance/((n-1)*nprocs), maxbonddim, direction=:backward, random_update) - Ci = TCI.sitetensor(C, last_site) - Cip1 = TCI.sitetensor(C, last_site+1) + Ci_local = TCI.sitetensor(C, last_site) + Cip1_local = TCI.sitetensor(C, last_site+1) - reqs = MPI.Isend(collect(size(Ci)), comm; dest=mpirank+1, tag=3*juliarank) - reqs1 = MPI.Isend(collect(size(Cip1)), comm; dest=mpirank+1, tag=3*juliarank+1) + reqs = MPI.Isend(collect(size(Ci_local)), comm; dest=mpirank+1, tag=3*juliarank) + reqs1 = MPI.Isend(collect(size(Cip1_local)), comm; dest=mpirank+1, tag=3*juliarank+1) MPI.Waitall([reqs, reqs1]) - reqs = MPI.Isend(Ci, comm; dest=mpirank+1, tag=3*juliarank) - reqs1 = MPI.Isend(Cip1, comm; dest=mpirank+1, tag=3*juliarank+1) + reqs = MPI.Isend(Ci_local, comm; dest=mpirank+1, tag=3*juliarank) + reqs1 = MPI.Isend(Cip1_local, comm; dest=mpirank+1, tag=3*juliarank+1) MPI.Waitall([reqs, reqs1]) rightenvironment!(Rs, A, B, C, last_site+1; random_env, p) @@ -1483,20 +1490,23 @@ function contract_distr_fit( MPI.Recv!(sizes, comm; source=mpirank-1, tag=3*(juliarank-1)) MPI.Recv!(sizes1, comm; source=mpirank-1, tag=3*(juliarank-1)+1) - Ci = ones(ValueType, sizes[1], sizes[2], sizes[3], sizes[4]) - Cip1 = ones(ValueType, sizes1[1], sizes1[2], sizes1[3], sizes1[4]) + Ci_local = ones(ValueType, sizes[1], sizes[2], sizes[3], sizes[4]) + Cip1_local = ones(ValueType, sizes1[1], sizes1[2], sizes1[3], sizes1[4]) - MPI.Recv!(Ci, comm; source=mpirank-1, tag=3*(juliarank-1)) - MPI.Recv!(Cip1, comm; source=mpirank-1, tag=3*(juliarank-1)+1) + MPI.Recv!(Ci_local, comm; source=mpirank-1, tag=3*(juliarank-1)) + MPI.Recv!(Cip1_local, comm; source=mpirank-1, tag=3*(juliarank-1)+1) - settwositetensors!(C, first_site-1, Ci, Cip1) + settwositetensors!(C, first_site-1, Ci_local, Cip1_local) movecenterright!(C) leftenvironment!(Ls, A, B, C, first_site-1; random_env, p) end end end + # disc is already defined in the if/else blocks above, but ensure it's defined + # (it may not be if MPI.Initialized() block executed and didn't define it) + # disc is already accumulated in tot_disc in the loops above, so this is just for safety tot_disc += disc converged = tot_disc < tolerance @@ -1663,17 +1673,17 @@ function contract_distr_fit( received_sitetensors = Vector{Array{ValueType,4}}(undef, n) for i in 1:n if juliarank == 1 - Ci = TCI.sitetensor(C, i) - sz = Int[size(Ci, 1), size(Ci, 2), size(Ci, 3), size(Ci, 4)] + Ci_local = TCI.sitetensor(C, i) + sz = Int[size(Ci_local, 1), size(Ci_local, 2), size(Ci_local, 3), size(Ci_local, 4)] + buf = Ci_local else sz = Vector{Int}(undef, 4) + buf = nothing # Will be allocated below end # Broadcast size MPI.Bcast!(sz, comm; root=0) # Broadcast data - if juliarank == 1 - buf = Ci - else + if juliarank != 1 buf = Array{ValueType,4}(undef, sz...) end MPI.Bcast!(buf, comm; root=0) @@ -1766,10 +1776,10 @@ function contract( error("Fit/distributed fit contraction cannot use a function. Use algorithm=:TCI with TCI.TensorTrain instead.") end - if algorithm === :fit - mpo = contract_fit(A, B; tolerance=tolerance, maxbonddim=maxbonddim, method=method, kwargs...) + mpo = if algorithm === :fit + contract_fit(A, B; tolerance=tolerance, maxbonddim=maxbonddim, method=method, kwargs...) elseif algorithm === :distrfit - mpo = contract_distr_fit(A, B; tolerance=tolerance, maxbonddim=maxbonddim, method=method, subcomm=subcomm, kwargs...) + contract_distr_fit(A, B; tolerance=tolerance, maxbonddim=maxbonddim, method=method, subcomm=subcomm, kwargs...) elseif algorithm === :TCI || algorithm === :naive || algorithm === :zipup # Convert to TensorTrain for these algorithms SiteTensorTrain{promote_type(ValueType1,ValueType2),4}( diff --git a/src/tensortrains.jl b/src/tensortrains.jl index 665922f..9b664a6 100644 --- a/src/tensortrains.jl +++ b/src/tensortrains.jl @@ -574,6 +574,29 @@ function SiteTensorTrain(tt::TCI.AbstractTensorTrain{ValueType}, center::Int, pa return SiteTensorTrain{ValueType, ndims(TCI.sitetensors(tt)[1])}(tt, center, partition) end +# Convert InverseTensorTrain to SiteTensorTrain +function SiteTensorTrain{ValueType,N}(tt::InverseTensorTrain{ValueType,N}, center::Int, partition::AbstractRange{<:Integer})::SiteTensorTrain{ValueType,N} where {ValueType,N} + # Convert InverseTensorTrain to TensorTrain first, then to SiteTensorTrain + tt_tensor = TCI.TensorTrain{ValueType,N}(tt) + return SiteTensorTrain{ValueType,N}(tt_tensor, center, partition) +end + +function SiteTensorTrain{ValueType,N}(tt::InverseTensorTrain{ValueType,N}, center::Int)::SiteTensorTrain{ValueType,N} where {ValueType,N} + n = length(tt) + return SiteTensorTrain{ValueType,N}(tt, center, 1:n) +end + +function SiteTensorTrain{ValueType,N}(tt::InverseTensorTrain{ValueType,N})::SiteTensorTrain{ValueType,N} where {ValueType,N} + n = length(tt) + return SiteTensorTrain{ValueType,N}(tt, 1, 1:n) +end + +# Base.convert for InverseTensorTrain to SiteTensorTrain +function Base.convert(::Type{SiteTensorTrain{ValueType,N}}, tt::InverseTensorTrain{ValueType,N})::SiteTensorTrain{ValueType,N} where {ValueType,N} + n = length(tt) + return SiteTensorTrain{ValueType,N}(tt, 1, 1:n) +end + # Type conversion: change element type of a SiteTensorTrain function SiteTensorTrain{ValueType2,N}(tt::SiteTensorTrain{ValueType1,N})::SiteTensorTrain{ValueType2,N} where {ValueType1,ValueType2,N} return SiteTensorTrain{ValueType2,N}(Array{ValueType2}.(TCI.sitetensors(tt)), center(tt), partition(tt)) @@ -760,6 +783,10 @@ function TCI.TensorTrain{ValueType,N}(tt::VidalTensorTrain{ValueType,N})::TCI.Te return TCI.TensorTrain{ValueType,N}(sitetensors) end +function TCI.TensorTrain{ValueType,N}(tt::SiteTensorTrain{ValueType,N})::TCI.TensorTrain{ValueType,N} where {ValueType,N} + return TCI.TensorTrain{ValueType,N}(TCI.sitetensors(tt)) +end + function TCI.TensorTrain(tt::SiteTensorTrain{ValueType,N})::TCI.TensorTrain{ValueType,N} where {ValueType,N} return TCI.TensorTrain{ValueType,N}(TCI.sitetensors(tt)) end diff --git a/test/test_with_jet.jl b/test/test_with_jet.jl index aa23a1f..cfa6d20 100644 --- a/test/test_with_jet.jl +++ b/test/test_with_jet.jl @@ -3,6 +3,7 @@ import T4AMPOContractions as MPO @testset "JET" begin if VERSION ≥ v"1.10" - JET.test_package(MPO; target_defined_modules=true) + # Use target_modules instead of deprecated target_defined_modules + JET.test_package(MPO; target_modules=(MPO,)) end end diff --git a/test_output.log b/test_output.log index 693d4b1..b4fe60e 100644 --- a/test_output.log +++ b/test_output.log @@ -1,23 +1,25 @@ -ERROR: LoadError: ArgumentError: Package Aqua not found in current path. -- Run `import Pkg; Pkg.add("Aqua")` to install the Aqua package. +┌ Warning: Skipping Aqua tests: LoadError("/Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/test_with_aqua.jl", 1, ArgumentError("Package Aqua not found in current path.\n- Run `import Pkg; Pkg.add(\"Aqua\")` to install the Aqua package.")) +└ @ Main ~/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:9 +ERROR: LoadError: ArgumentError: Package JET not found in current path. +- Run `import Pkg; Pkg.add("JET")` to install the JET package. Stacktrace: - [1] macro expansion - @ ./loading.jl:2400 [inlined] - [2] macro expansion - @ ./lock.jl:376 [inlined] - [3] __require(into::Module, mod::Symbol) - @ Base ./loading.jl:2383 - [4] require(into::Module, mod::Symbol) - @ Base ./loading.jl:2359 - [5] include(mapexpr::Function, mod::Module, _path::String) - @ Base ./Base.jl:307 + [1] macro expansion + @ ./loading.jl:2403 [inlined] + [2] macro expansion + @ ./lock.jl:376 [inlined] + [3] __require(into::Module, mod::Symbol) + @ Base ./loading.jl:2386 + [4] require(into::Module, mod::Symbol) + @ Base ./loading.jl:2362 + [5] include(mapexpr::Function, mod::Module, _path::String) + @ Base ./Base.jl:307 [6] top-level scope - @ ~/projects/JuliaUmbrella/T4AMPOContractions.jl/test/runtests.jl:5 - [7] include(mod::Module, _path::String) - @ Base ./Base.jl:306 - [8] exec_options(opts::Base.JLOptions) - @ Base ./client.jl:317 - [9] _start() - @ Base ./client.jl:550 -in expression starting at /Users/hiroshi/projects/JuliaUmbrella/T4AMPOContractions.jl/test/test_with_aqua.jl:1 -in expression starting at /Users/hiroshi/projects/JuliaUmbrella/T4AMPOContractions.jl/test/runtests.jl:5 + @ ~/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:11 + [7] include(mod::Module, _path::String) + @ Base ./Base.jl:306 + [8] exec_options(opts::Base.JLOptions) + @ Base ./client.jl:317 + [9] _start() + @ Base ./client.jl:550 +in expression starting at /Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/test_with_jet.jl:1 +in expression starting at /Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:11 diff --git a/test_output_head.log b/test_output_head.log new file mode 100644 index 0000000..f3ac912 --- /dev/null +++ b/test_output_head.log @@ -0,0 +1,37 @@ +Precompiling packages... +Info Given T4AMPOContractions was explicitly requested, output will be shown live  +WARNING: Imported binding T4ATensorCI.swaprow! was undeclared at import time during import to T4AMPOContractions. +WARNING: Imported binding T4ATensorCI.swapcol! was undeclared at import time during import to T4AMPOContractions. +WARNING: Imported binding T4ATensorCI._optimizerrlu! was undeclared at import time during import to T4AMPOContractions. +WARNING: Imported binding T4ATensorCI.cols2Lmatrix! was undeclared at import time during import to T4AMPOContractions. +WARNING: Imported binding T4ATensorCI.rows2Umatrix! was undeclared at import time during import to T4AMPOContractions. +WARNING: Imported binding T4ATensorCI.solve was undeclared at import time during import to T4AMPOContractions. + 1381.2 ms ✓ T4AMPOContractions + 1 dependency successfully precompiled in 1 seconds. 62 already precompiled. + 1 dependency had output during precompilation: +┌ T4AMPOContractions +│ [Output was shown above] +└  +ERROR: LoadError: ArgumentError: Package Aqua not found in current path. +- Run `import Pkg; Pkg.add("Aqua")` to install the Aqua package. +Stacktrace: + [1] macro expansion + @ ./loading.jl:2403 [inlined] + [2] macro expansion + @ ./lock.jl:376 [inlined] + [3] __require(into::Module, mod::Symbol) + @ Base ./loading.jl:2386 + [4] require(into::Module, mod::Symbol) + @ Base ./loading.jl:2362 + [5] include(mapexpr::Function, mod::Module, _path::String) + @ Base ./Base.jl:307 + [6] top-level scope + @ ~/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:5 + [7] include(mod::Module, _path::String) + @ Base ./Base.jl:306 + [8] exec_options(opts::Base.JLOptions) + @ Base ./client.jl:317 + [9] _start() + @ Base ./client.jl:550 +in expression starting at /Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/test_with_aqua.jl:1 +in expression starting at /Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:5 diff --git a/test_output_tail.log b/test_output_tail.log new file mode 100644 index 0000000..8522217 --- /dev/null +++ b/test_output_tail.log @@ -0,0 +1,50 @@ +  @ Base ./Base.jl:307 + [8] top-level scope +  @ ~/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:19 + [9] include(mod::Module, _path::String) +  @ Base ./Base.jl:306 + [10] exec_options(opts::Base.JLOptions) +  @ Base ./client.jl:317 + [11] _start() +  @ Base ./client.jl:550 +encode and decode cachekey: Error During Test at /Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/test_cachedfunction.jl:144 + Got exception outside of a @test + UndefVarError: `CachedFunction` not defined in `T4AMPOContractions` + Suggestion: check for spelling errors or missing imports. + Stacktrace: + [1] getproperty(x::Module, f::Symbol) +  @ Base ./Base_compiler.jl:47 + [2] top-level scope +  @ ~/projects/tensor4all/T4AMPOContractions.jl/test/test_cachedfunction.jl:48 + [3] macro expansion +  @ ~/.julia/juliaup/julia-1.12.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Test/src/Test.jl:1776 [inlined] + [4] macro expansion +  @ ~/projects/tensor4all/T4AMPOContractions.jl/test/test_cachedfunction.jl:145 [inlined] + [5] macro expansion +  @ ~/.julia/juliaup/julia-1.12.3+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Test/src/Test.jl:1776 [inlined] + [6] macro expansion +  @ ~/projects/tensor4all/T4AMPOContractions.jl/test/test_cachedfunction.jl:146 [inlined] + [7] include(mapexpr::Function, mod::Module, _path::String) +  @ Base ./Base.jl:307 + [8] top-level scope +  @ ~/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:19 + [9] include(mod::Module, _path::String) +  @ Base ./Base.jl:306 + [10] exec_options(opts::Base.JLOptions) +  @ Base ./client.jl:317 + [11] _start() +  @ Base ./client.jl:550 +Test Summary: | Error Total Time +Cached Function |  8  8 1.1s + cache |  1  1 0.9s + cache |  1  1 0.0s + cache(batcheval) |  1  1 0.0s + cache(batcheval) |  1  1 0.0s + many bits |  1  1 0.0s + key collision and memory overhead |  1  1 0.0s + computekey boundary check |  1  1 0.0s + encode and decode cachekey |  1  1 0.0s +RNG of the outermost testset: Random.Xoshiro(0x6d9a1ba6f73d86ef, 0x90e61232830fa96f, 0x9440ed04f01d93cd, 0x2a5f905b05cacfee, 0x2e2de5d4598c15bf) +ERROR: LoadError: Some tests did not pass: 0 passed, 0 failed, 8 errored, 0 broken. +in expression starting at /Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/test_cachedfunction.jl:47 +in expression starting at /Users/hiroshi/projects/tensor4all/T4AMPOContractions.jl/test/runtests.jl:19