Skip to content

Commit 07382f9

Browse files
authored
[NDTensors] [ITensors] Simplify block sparse multithreading implementation (#1049)
- Rewrite and reorganize sequential and multithreaded block sparse contraction, making use of `Folds.foreach` to clean up the code, make some parts more generic to sequential vs. threaded execution, as well as reorganizing to make it easier to try out different algorithms and backends. - New benchmark for sequential and threaded block sparse contraction, based on the application of a 2-site effective Hamiltonian with tensor sparsity structure saved from a hybrid momentum space Hubbard model DMRG calculation with bond dimension 3000. The indices and fluxes of the tensors in the contraction are saved as HDF5 files so that random ITensors with the same block structure can be reproduced for benchmarking. - Allow specifying a random number generator when constructing random ITensors and MPS by passing an RNG as the first input. Defaults to the default global RNG from Julia. - Allow overloading `orthogonalize!` by dispatching on a projected MPO type in DMRG, which makes it easier to implement MPI parallelized sums of MPOs in ITensor/ITensorParallel.jl#15.
1 parent 896a91d commit 07382f9

47 files changed

Lines changed: 1493 additions & 680 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/benchmark.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ on:
66
jobs:
77
Benchmark:
88
runs-on: ubuntu-latest
9+
env:
10+
JULIA_NUM_THREADS: 2
911
steps:
1012
- uses: actions/checkout@v2
1113
- uses: julia-actions/setup-julia@latest

.github/workflows/format_check.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Format check
22
on:
33
push:
4-
branches: [master]
4+
branches: [main]
55
tags: [v*]
66
pull_request:
77

ITensorGPU/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ITensorGPU: Intelligent Tensors with GPU acceleration
22

3-
[![codecov](https://codecov.io/gh/ITensor/ITensorGPU.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/ITensor/ITensorGPU.jl)
3+
[![codecov](https://codecov.io/gh/ITensor/ITensorGPU.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ITensor/ITensorGPU.jl)
44

55
[![gitlab-ci](https://gitlab.com/JuliaGPU/ITensorGPU-jl/badges/master/pipeline.svg)](https://gitlab.com/JuliaGPU/ITensorGPU-jl/commits/master)
66

NDTensors/Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ version = "0.1.46"
77
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
88
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
99
Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4"
10+
FLoops = "cc61a311-1640-44b5-9fba-1b764f453329"
11+
Folds = "41a02a25-b8f0-4f67-bc48-60067656b558"
1012
Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196"
1113
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
1214
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1315
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
1416
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
1517
SimpleTraits = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
18+
SplitApplyCombine = "03a91e81-4c3e-53e1-a0a4-9c0c8f19dd66"
1619
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1720
Strided = "5e0ebb24-38b0-5f93-81fe-25c709ecae67"
1821
TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
@@ -22,10 +25,13 @@ TupleTools = "9d95972d-f1c8-5527-a6e0-b4b365fa01f6"
2225
Adapt = "3.5"
2326
Compat = "2.1, 3, 4"
2427
Dictionaries = "0.3.5"
28+
FLoops = "0.2.1"
29+
Folds = "0.2.8"
2530
Functors = "0.2, 0.3, 0.4"
2631
HDF5 = "0.14, 0.15, 0.16"
2732
Requires = "1.1"
2833
SimpleTraits = "0.9.4"
34+
SplitApplyCombine = "1.2.2"
2935
StaticArrays = "0.12, 1.0"
3036
Strided = "0.3, 1"
3137
TimerOutputs = "0.5.5"

NDTensors/src/NDTensors.jl

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@ using Adapt
44
using Base.Threads
55
using Compat
66
using Dictionaries
7+
using FLoops
8+
using Folds
79
using Random
810
using LinearAlgebra
911
using StaticArrays
1012
using Functors
1113
using HDF5
1214
using Requires
1315
using SimpleTraits
16+
using SplitApplyCombine
1417
using Strided
1518
using TimerOutputs
1619
using TupleTools
@@ -28,8 +31,9 @@ include("imports.jl")
2831
include("exports.jl")
2932

3033
#####################################
31-
# DenseTensor and DiagTensor
34+
# General functionality
3235
#
36+
include("algorithm.jl")
3337
include("aliasstyle.jl")
3438
include("abstractarray/set_types.jl")
3539
include("abstractarray/to_shape.jl")
@@ -46,6 +50,10 @@ include("tensor/similar.jl")
4650
include("adapt.jl")
4751
include("generic_tensor_operations.jl")
4852
include("contraction_logic.jl")
53+
54+
#####################################
55+
# DenseTensor and DiagTensor
56+
#
4957
include("dense/dense.jl")
5058
#include("dense/adapt.jl")
5159
include("fill.jl")
@@ -65,6 +73,12 @@ include("blocksparse/block.jl")
6573
include("blocksparse/blockoffsets.jl")
6674
include("blocksparse/blocksparse.jl")
6775
include("blocksparse/blocksparsetensor.jl")
76+
include("blocksparse/contract.jl")
77+
include("blocksparse/contract_utilities.jl")
78+
include("blocksparse/contract_generic.jl")
79+
include("blocksparse/contract_sequential.jl")
80+
include("blocksparse/contract_folds.jl")
81+
include("blocksparse/contract_threads.jl")
6882
include("blocksparse/diagblocksparse.jl")
6983
include("blocksparse/similar.jl")
7084
include("blocksparse/combiner.jl")
@@ -91,7 +105,7 @@ const timer = TimerOutput()
91105
# Optional block sparse multithreading
92106
#
93107

94-
include("blas_get_num_threads.jl")
108+
blas_get_num_threads() = BLAS.get_num_threads()
95109

96110
const _using_threaded_blocksparse = Ref(false)
97111

@@ -134,9 +148,9 @@ function _enable_threaded_blocksparse()
134148
"WARNING: You are trying to enable block sparse multithreading, but you have started Julia with only a single thread. You can start Julia with `N` threads with `julia -t N`, and check the number of threads Julia can use with `Threads.nthreads()`. Your system has $(Sys.CPU_THREADS) threads available to use, which you can determine by running `Sys.CPU_THREADS`.\n",
135149
)
136150
end
137-
if blas_get_num_threads() > 1 && Threads.nthreads() > 1
151+
if BLAS.get_num_threads() > 1 && Threads.nthreads() > 1
138152
println(
139-
"WARNING: You are enabling block sparse multithreading, but BLAS $(BLAS.vendor()) is currently set to use $(blas_get_num_threads()) threads. When using block sparse multithreading, we recommend setting BLAS to use only a single thread, otherwise you may see suboptimal performance. You can set it with `using LinearAlgebra; BLAS.set_num_threads(1)`.\n",
153+
"WARNING: You are enabling block sparse multithreading, but your BLAS configuration $(BLAS.get_config()) is currently set to use $(BLAS.get_num_threads()) threads. When using block sparse multithreading, we recommend setting BLAS to use only a single thread, otherwise you may see suboptimal performance. You can set it with `using LinearAlgebra; BLAS.set_num_threads(1)`.\n",
140154
)
141155
end
142156
if Strided.get_num_threads() > 1
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use the same interface.
1212
struct Algorithm{Alg} end
1313

1414
Algorithm(s) = Algorithm{Symbol(s)}()
15-
algorithm(::Algorithm{Alg}) where {Alg} = string(Alg)
15+
algorithm_string(::Algorithm{Alg}) where {Alg} = string(Alg)
1616

17-
show(io::IO, alg::Algorithm) = print(io, "Algorithm type ", algorithm(alg))
17+
show(io::IO, alg::Algorithm) = print(io, "Algorithm type ", algorithm_string(alg))
1818
print(io::IO, ::Algorithm{Alg}) where {Alg} = print(io, Alg)
1919

2020
"""

NDTensors/src/blas_get_num_threads.jl

Lines changed: 0 additions & 3 deletions
This file was deleted.

NDTensors/src/blocksparse/blockoffsets.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ const BlockOffsets{N} = Dictionary{Block{N},Int}
1010

1111
BlockOffset(block::Block{N}, offset::Int) where {N} = BlockOffset{N}(block, offset)
1212

13+
ndims(::Blocks{N}) where {N} = N
14+
ndims(::BlockOffset{N}) where {N} = N
15+
ndims(::BlockOffsets{N}) where {N} = N
16+
17+
blocktype(bofs::BlockOffsets) = keytype(bofs)
18+
1319
nzblock(bof::BlockOffset) = first(bof)
1420

1521
offset(bof::BlockOffset) = last(bof)

NDTensors/src/blocksparse/blocksparse.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,15 @@ end
7474
#
7575

7676
function randn(
77-
::Type{<:BlockSparse{ElT}}, blockoffsets::BlockOffsets, dim::Integer
77+
StorageT::Type{<:BlockSparse{ElT}}, blockoffsets::BlockOffsets, dim::Integer
7878
) where {ElT<:Number}
79-
return BlockSparse(randn(ElT, dim), blockoffsets)
79+
return randn(Random.default_rng(), StorageT, blockoffsets, dim)
80+
end
81+
82+
function randn(
83+
rng::AbstractRNG, ::Type{<:BlockSparse{ElT}}, blockoffsets::BlockOffsets, dim::Integer
84+
) where {ElT<:Number}
85+
return BlockSparse(randn(rng, ElT, dim), blockoffsets)
8086
end
8187

8288
#function BlockSparse{ElR}(data::VecT,offsets) where {ElR,VecT<:AbstractVector{ElT}} where {ElT}

0 commit comments

Comments
 (0)