Skip to content

[ITensors] [BUG] Different results when using BLAS multithreading #1699

Description

@MaryamR99

Description of bug

When I use BLAS.set_num_threads(1), I get a different result than when I set it to 4 (or a different number other than 1).

Minimal code demonstrating the bug or unexpected behavior

Minimal runnable code

using ITensorMPS, ITensors, LinearAlgebra, Random

function run_test(thread_count::Int, N, p, χ, angle)

    BLAS.set_num_threads(thread_count)
    
    Random.seed!(1234)
    println("Using N = $N, χ = , Threads = $thread_count")
    s = siteinds("S=1/2", N)
    ψ = randomMPS(s; linkdims=χ)

    angles_1 = fill(angle, p)
    angles_2 = fill(angle, p)
    for k in 1:p

        for n1 in 1:N
            
            for n2 in n1+1:N

                ϕ = copy(ψ)
                gate = op("Z", s, n1) 
                ϕ[n1] = noprime( gate* ϕ[n1])

                gate = op("Z", s, n2) 
                ϕ[n2] = noprime( gate* ϕ[n2])
                sine, cose = sincos(angles_1[k])

                ψ_sum = +(cose * ψ, 1im * sine * ϕ; alg="directsum")

                truncate!(ψ_sum; maxdim=χ)
                normalize!(ψ_sum)

                ψ = ψ_sum
            end
        end
            
        for i in 1:N
            gateX = op("X", s, i)
            gatee = cos(angles_2[k]) * op("Id", s, i) - 1im * sin(angles_2[k]) * gateX
            ψ[i] = noprime( gatee * ψ[i])
        end
    end


    H_C = 0.0
    for n1 in 1:N
        for n2 in n1+1:N

            ϕ = copy(ψ)
            gate = op("Z", s, n1) 
            noprime!(ϕ[n1] *= gate)

            gate = op("Z", s, n2) 
            noprime!(ϕ[n2] *= gate)

            # Compute ⟨ψ|Z_i Z_j|ψ⟩
            zz_expectation = ITensorMPS.inner(ψ, ϕ)
            H_C +=  real(zz_expectation)
        end
    end
    return H_C, ψ
end




println("--- Starting Reproducibility Test ---")

N = 16
p = 20
χ = 40
angle = 0.3

println(Threads.nthreads())


println("Running with 1 thread...")
H_ref, ψ_ref = run_test(1, N, p, χ, angle)



println("Running with 4 threads...") 
H_test, ψ_test = run_test(4, N, p, χ, angle) 


# Compare


println("\n------------------------------------------------")
println("Results:")
println("H_ref:  $H_ref")
println("H_test: $H_test")

println("state overlap: ", abs(ITensorMPS.inner(ψ_ref, ψ_test)))

Expected output or behavior

The expectation value of the energy should be the same, between the two cases.
Also, the overlap of the final states, |<ψ_ref|ψ_test>|, should be almost 1.

H_ref:  2.451631441113766
H_test: 2.4615310779333828
state overlap: 0.9984877783164545

Version information

  • Output from versioninfo():
julia> versioninfo()
Julia Version 1.12.4
Commit 01a2eadb047 (2026-01-06 16:56 UTC)
Build Info:
  Official https://julialang.org release
Platform Info:
  OS: macOS (arm64-apple-darwin24.0.0)
  CPU: 8 × Apple M3
  WORD_SIZE: 64
  LLVM: libLLVM-18.1.7 (ORCJIT, apple-m3)
  GC: Built with stock GC
Threads: 1 default, 1 interactive, 1 GC (on 4 virtual cores)
  • Output from using Pkg; Pkg.status("ITensors"):
julia> using Pkg; Pkg.status("ITensors")
  [9136182c] ITensors v0.9.18

Metadata

Metadata

Assignees

No one assigned

    Labels

    ITensorsIssues or pull requests related to the `ITensors` package.bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions