diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml index 0614de9..70f2dc6 100644 --- a/.github/workflows/CompatHelper.yml +++ b/.github/workflows/CompatHelper.yml @@ -1,13 +1,11 @@ name: "CompatHelper" - on: schedule: - - cron: '0 0 * * *' - workflow_dispatch: + - cron: "0 0 * * *" + workflow_dispatch: ~ permissions: - contents: write - pull-requests: write - + contents: "write" + pull-requests: "write" jobs: compat-helper: name: "CompatHelper" diff --git a/.github/workflows/Documentation.yml b/.github/workflows/Documentation.yml index 01a7f7a..c3b11ec 100644 --- a/.github/workflows/Documentation.yml +++ b/.github/workflows/Documentation.yml @@ -1,23 +1,20 @@ name: "Documentation" - on: push: branches: - - main - tags: '*' - pull_request: + - "main" + tags: "*" + pull_request: ~ schedule: - - cron: '1 4 * * 4' - + - cron: "1 4 * * 4" concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: ${{ github.ref_name != github.event.repository.default_branch || github.ref != 'refs/tags/v*' }} - + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: "${{ github.ref_name != github.event.repository.default_branch || github.ref != 'refs/tags/v*' }}" jobs: build-and-deploy-docs: name: "Documentation" uses: "ITensor/ITensorActions/.github/workflows/Documentation.yml@main" with: - localregistry: https://github.com/ITensor/ITensorRegistry.git + localregistry: "https://github.com/ITensor/ITensorRegistry.git" secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}" diff --git a/.github/workflows/FormatCheck.yml b/.github/workflows/FormatCheck.yml index 1525861..596c76c 100644 --- a/.github/workflows/FormatCheck.yml +++ b/.github/workflows/FormatCheck.yml @@ -1,15 +1,17 @@ name: "Format Check" - on: pull_request_target: - paths: ['**/*.jl'] - types: [opened, synchronize, reopened, ready_for_review] - + paths: + - "**/*.jl" + types: + - "opened" + - "synchronize" + - "reopened" + - "ready_for_review" permissions: - contents: read - actions: write - pull-requests: write - + contents: "read" + actions: "write" + pull-requests: "write" jobs: format-check: name: "Format Check" diff --git a/.github/workflows/FormatPullRequest.yml b/.github/workflows/FormatPullRequest.yml index 93875cc..b9a329c 100644 --- a/.github/workflows/FormatPullRequest.yml +++ b/.github/workflows/FormatPullRequest.yml @@ -1,13 +1,11 @@ name: "Format Pull Request" - on: schedule: - - cron: '0 0 * * *' - workflow_dispatch: + - cron: "0 0 * * *" + workflow_dispatch: ~ permissions: - contents: write - pull-requests: write - + contents: "write" + pull-requests: "write" jobs: format-pull-request: name: "Format Pull Request" diff --git a/.github/workflows/IntegrationTest.yml b/.github/workflows/IntegrationTest.yml index 585fd31..1868aae 100644 --- a/.github/workflows/IntegrationTest.yml +++ b/.github/workflows/IntegrationTest.yml @@ -1,25 +1,27 @@ name: "IntegrationTest" - on: push: branches: - - 'main' - tags: '*' + - "main" + tags: "*" paths: - - 'Project.toml' + - "Project.toml" pull_request: - paths: - - 'Project.toml' - + types: + - "opened" + - "synchronize" + - "reopened" + - "ready_for_review" + - "converted_to_draft" jobs: integration-test: name: "IntegrationTest" strategy: - matrix: - pkg: - - 'FusionTensors' - - 'GradedArrays' - - 'KroneckerArrays' + matrix: + pkg: + - "FusionTensors" + - "GradedArrays" + - "KroneckerArrays" uses: "ITensor/ITensorActions/.github/workflows/IntegrationTest.yml@main" with: localregistry: "https://github.com/ITensor/ITensorRegistry.git" diff --git a/.github/workflows/IntegrationTestRequest.yml b/.github/workflows/IntegrationTestRequest.yml index d42fcca..6f58e45 100644 --- a/.github/workflows/IntegrationTestRequest.yml +++ b/.github/workflows/IntegrationTestRequest.yml @@ -1,14 +1,14 @@ name: "Integration Test Request" - on: issue_comment: - types: [created] - + types: + - "created" jobs: integrationrequest: if: | github.event.issue.pull_request && contains(fromJSON('["OWNER", "COLLABORATOR", "MEMBER"]'), github.event.comment.author_association) - uses: ITensor/ITensorActions/.github/workflows/IntegrationTestRequest.yml@main + + uses: "ITensor/ITensorActions/.github/workflows/IntegrationTestRequest.yml@main" with: - localregistry: https://github.com/ITensor/ITensorRegistry.git + localregistry: "https://github.com/ITensor/ITensorRegistry.git" diff --git a/.github/workflows/LiterateCheck.yml b/.github/workflows/LiterateCheck.yml index 2ca5f27..efa25ca 100644 --- a/.github/workflows/LiterateCheck.yml +++ b/.github/workflows/LiterateCheck.yml @@ -1,15 +1,13 @@ name: "Literate Check" - on: push: branches: - - 'main' - tags: '*' - pull_request: - + - "main" + tags: "*" + pull_request: ~ jobs: literate: name: "Literate Check" uses: "ITensor/ITensorActions/.github/workflows/LiterateCheck.yml@main" with: - localregistry: https://github.com/ITensor/ITensorRegistry.git + localregistry: "https://github.com/ITensor/ITensorRegistry.git" diff --git a/.github/workflows/Registrator.yml b/.github/workflows/Registrator.yml index 4ae82c4..00bf06c 100644 --- a/.github/workflows/Registrator.yml +++ b/.github/workflows/Registrator.yml @@ -1,21 +1,19 @@ -name: Register Package +name: "Register Package" on: - workflow_dispatch: + workflow_dispatch: ~ push: branches: - - 'master' - - 'main' + - "master" + - "main" paths: - - 'Project.toml' - + - "Project.toml" permissions: - contents: write - pull-requests: write - + contents: "write" + pull-requests: "write" jobs: Register: uses: "ITensor/ITensorActions/.github/workflows/Registrator.yml@main" with: - localregistry: ITensor/ITensorRegistry + localregistry: "ITensor/ITensorRegistry" secrets: - REGISTRATOR_KEY: ${{ secrets.REGISTRATOR_KEY }} + REGISTRATOR_KEY: "${{ secrets.REGISTRATOR_KEY }}" diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index 0cd3114..089c0de 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -1,31 +1,15 @@ -name: TagBot +name: "TagBot" on: issue_comment: types: - - created - workflow_dispatch: - inputs: - lookback: - default: "3" -permissions: - actions: read - checks: read - contents: write - deployments: read - issues: read - discussions: read - packages: read - pages: read - pull-requests: read - repository-projects: read - security-events: read - statuses: read + - "created" + workflow_dispatch: [] jobs: TagBot: - if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' - runs-on: ubuntu-latest + if: "github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'" + runs-on: "ubuntu-latest" steps: - - uses: JuliaRegistries/TagBot@v1 + - uses: "JuliaRegistries/TagBot@v1" with: - token: ${{ secrets.GITHUB_TOKEN }} - ssh: ${{ secrets.DOCUMENTER_KEY }} + token: "${{ secrets.GITHUB_TOKEN }}" + ssh: "${{ secrets.DOCUMENTER_KEY }}" diff --git a/.github/workflows/Tests.yml b/.github/workflows/Tests.yml index 5a0a306..e3a94c5 100644 --- a/.github/workflows/Tests.yml +++ b/.github/workflows/Tests.yml @@ -1,21 +1,24 @@ -name: Tests +name: "Tests" on: push: branches: - - 'master' - - 'main' - - 'release-' - tags: '*' + - "master" + - "main" + - "release-" + tags: "*" paths-ignore: - - 'docs/**' + - "docs/**" pull_request: - workflow_dispatch: - + types: + - "opened" + - "synchronize" + - "reopened" + - "ready_for_review" + - "converted_to_draft" + workflow_dispatch: ~ concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - # Cancel intermediate builds: only if it is a pull request build. - cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} - + group: "${{ github.workflow }}-${{ github.ref }}" + cancel-in-progress: "${{ startsWith(github.ref, 'refs/pull/') }}" jobs: tests: name: "Tests" @@ -23,20 +26,17 @@ jobs: fail-fast: false matrix: version: - - 'lts' # minimal supported version - - '1' # latest released Julia version - # group: - # - 'core' - # - 'optional' + - "lts" + - "1" os: - - ubuntu-latest - - macOS-latest - - windows-latest + - "ubuntu-latest" + - "macOS-latest" + - "windows-latest" uses: "ITensor/ITensorActions/.github/workflows/Tests.yml@main" with: group: "${{ matrix.group }}" julia-version: "${{ matrix.version }}" os: "${{ matrix.os }}" - localregistry: https://github.com/ITensor/ITensorRegistry.git + localregistry: "https://github.com/ITensor/ITensorRegistry.git" secrets: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}" diff --git a/.github/workflows/VersionCheck.yml b/.github/workflows/VersionCheck.yml index 69444f1..bb0df88 100644 --- a/.github/workflows/VersionCheck.yml +++ b/.github/workflows/VersionCheck.yml @@ -1,11 +1,9 @@ name: "Version Check" - on: - pull_request: - + pull_request: ~ jobs: version-check: name: "Version Check" uses: "ITensor/ITensorActions/.github/workflows/VersionCheck.yml@main" with: - localregistry: https://github.com/ITensor/ITensorRegistry.git + localregistry: "https://github.com/ITensor/ITensorRegistry.git" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3fc4743..49fe94e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,17 +1,17 @@ ci: - skip: [runic] - + skip: + - "itensor-formatter" repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 - hooks: - - id: check-merge-conflict - - id: check-toml - - id: check-yaml - - id: end-of-file-fixer - exclude_types: [markdown] # incompatible with Literate.jl - -- repo: https://github.com/fredrikekre/runic-pre-commit - rev: v2.0.1 - hooks: - - id: runic + - repo: "https://github.com/pre-commit/pre-commit-hooks" + rev: "v6.0.0" + hooks: + - id: "check-merge-conflict" + - id: "check-toml" + - id: "check-yaml" + - id: "end-of-file-fixer" + exclude_types: + - "markdown" + - repo: "https://github.com/ITensor/ITensorFormatter.jl" + rev: "v0.2.9" + hooks: + - id: "itensor-formatter" diff --git a/Project.toml b/Project.toml index fa09b82..85fb3d5 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "BlockSparseArrays" uuid = "2c9a651f-6452-4ace-a6ac-809f4280fbb4" -version = "0.10.20" +version = "0.10.21" authors = ["ITensor developers and contributors"] [workspace] diff --git a/README.md b/README.md index 11ae916..78e174b 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![Coverage](https://codecov.io/gh/ITensor/BlockSparseArrays.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ITensor/BlockSparseArrays.jl) [![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-4495d1.svg)](https://github.com/invenia/BlueStyle) [![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) +[![Code Style](https://img.shields.io/badge/code_style-ITensor-purple)](https://github.com/ITensor/ITensorFormatter.jl) A block sparse array type in Julia based on the [`BlockArrays.jl`](https://github.com/JuliaArrays/BlockArrays.jl) interface. diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl index 65c0acf..6eaac1a 100644 --- a/benchmark/benchmarks.jl +++ b/benchmark/benchmarks.jl @@ -1,5 +1,5 @@ -using BlockSparseArrays using BenchmarkTools +using BlockSparseArrays SUITE = BenchmarkGroup() SUITE["rand"] = @benchmarkable rand(10) diff --git a/docs/make.jl b/docs/make.jl index 39aab18..78ade73 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -17,11 +17,12 @@ makedocs(; format = Documenter.HTML(; canonical = "https://itensor.github.io/BlockSparseArrays.jl", edit_link = "main", - assets = ["assets/favicon.ico", "assets/extras.css"], + assets = ["assets/favicon.ico", "assets/extras.css"] ), - pages = ["Home" => "index.md", "Reference" => "reference.md"], + pages = ["Home" => "index.md", "Reference" => "reference.md"] ) deploydocs(; - repo = "github.com/ITensor/BlockSparseArrays.jl", devbranch = "main", push_preview = true + repo = "github.com/ITensor/BlockSparseArrays.jl", devbranch = "main", + push_preview = true ) diff --git a/docs/make_index.jl b/docs/make_index.jl index 0b2d95d..00f65be 100644 --- a/docs/make_index.jl +++ b/docs/make_index.jl @@ -1,5 +1,5 @@ -using Literate: Literate using BlockSparseArrays: BlockSparseArrays +using Literate: Literate function ccq_logo(content) include_ccq_logo = """ @@ -17,5 +17,5 @@ Literate.markdown( joinpath(pkgdir(BlockSparseArrays), "docs", "src"); flavor = Literate.DocumenterFlavor(), name = "index", - postprocess = ccq_logo, + postprocess = ccq_logo ) diff --git a/docs/make_readme.jl b/docs/make_readme.jl index ad2e38a..f406f0d 100644 --- a/docs/make_readme.jl +++ b/docs/make_readme.jl @@ -1,5 +1,5 @@ -using Literate: Literate using BlockSparseArrays: BlockSparseArrays +using Literate: Literate function ccq_logo(content) include_ccq_logo = """ @@ -17,5 +17,5 @@ Literate.markdown( joinpath(pkgdir(BlockSparseArrays)); flavor = Literate.CommonMarkFlavor(), name = "README", - postprocess = ccq_logo, + postprocess = ccq_logo ) diff --git a/ext/BlockSparseArraysTensorAlgebraExt/BlockSparseArraysTensorAlgebraExt.jl b/ext/BlockSparseArraysTensorAlgebraExt/BlockSparseArraysTensorAlgebraExt.jl index b2e411a..25384e0 100644 --- a/ext/BlockSparseArraysTensorAlgebraExt/BlockSparseArraysTensorAlgebraExt.jl +++ b/ext/BlockSparseArraysTensorAlgebraExt/BlockSparseArraysTensorAlgebraExt.jl @@ -59,7 +59,7 @@ function TensorAlgebra.unmatricize( ::BlockReshapeFusion, m::AbstractBlockSparseMatrix, codomain_axes::Tuple{Vararg{AbstractUnitRange}}, - domain_axes::Tuple{Vararg{AbstractUnitRange}}, + domain_axes::Tuple{Vararg{AbstractUnitRange}} ) ax = (codomain_axes..., domain_axes...) reshaped_blocks_m = reshape(blocks(m), blocklength.(ax)) @@ -69,7 +69,7 @@ function TensorAlgebra.unmatricize( map(ntuple(identity, length(ax))) do i return Base.axes1(ax[i][Block(I[i])]) end, - (length(codomain_axes), length(domain_axes)), + (length(codomain_axes), length(domain_axes)) ) return unmatricize(reshaped_blocks_m[I], block_axes_I) end diff --git a/src/BlockArraysExtensions/BlockArraysExtensions.jl b/src/BlockArraysExtensions/BlockArraysExtensions.jl index f8effec..1f73de6 100644 --- a/src/BlockArraysExtensions/BlockArraysExtensions.jl +++ b/src/BlockArraysExtensions/BlockArraysExtensions.jl @@ -1,32 +1,11 @@ using ArrayLayouts: ArrayLayouts, MemoryLayout, sub_materialize -using BlockArrays: - BlockArrays, - AbstractBlockArray, - AbstractBlockVector, - Block, - BlockIndex, - BlockIndexRange, - BlockRange, - BlockSlice, - BlockVector, - BlockedOneTo, - BlockedUnitRange, - BlockedVector, - block, - blockaxes, - blockedrange, - blockindex, - blocks, - findblock, +using BlockArrays: BlockArrays, AbstractBlockArray, AbstractBlockVector, Block, BlockIndex, + BlockIndexRange, BlockRange, BlockSlice, BlockVector, BlockedOneTo, BlockedUnitRange, + BlockedVector, block, blockaxes, blockedrange, blockindex, blocks, findblock, findblockindex using Dictionaries: Dictionary, Indices -using SparseArraysBase: - SparseArraysBase, - eachstoredindex, - getunstoredindex, - isstored, - setunstoredindex!, - storedlength +using SparseArraysBase: SparseArraysBase, eachstoredindex, getunstoredindex, isstored, + setunstoredindex!, storedlength function view!(a::AbstractArray{<:Any, N}, index::Block{N}) where {N} return view!(a, Tuple(index)...) @@ -85,7 +64,9 @@ struct NonBlockedArray{T, N, Array <: AbstractArray{T, N}} <: AbstractArray{T, N end Base.parent(a::NonBlockedArray) = a.array Base.size(a::NonBlockedArray) = size(parent(a)) -Base.getindex(a::NonBlockedArray{<:Any, N}, I::Vararg{Integer, N}) where {N} = parent(a)[I...] +function Base.getindex(a::NonBlockedArray{<:Any, N}, I::Vararg{Integer, N}) where {N} + return parent(a)[I...] +end # Views of `NonBlockedArray`/`NonBlockedVector` are eager. # This fixes an issue in Julia 1.11 where reindexing defaults to using views. # TODO: Maybe reconsider this design, and allows views to work in slicing. @@ -156,7 +137,9 @@ function Base.getindex( return NonBlockedVector(BlockIndices(S.blocks[Block(i)], S.indices[Block(i)])) end function Base.getindex( - S::BlockIndices{<:BlockedVector{<:Block{1}, <:BlockRange{1}}}, i::BlockSlice{<:Block{1}} + S::BlockIndices{<:BlockedVector{<:Block{1}, <:BlockRange{1}}}, i::BlockSlice{ + <:Block{1}, + } ) return i end @@ -190,7 +173,7 @@ function Base.getindex(S::BlockIndices, i::BlockSlice{<:BlockRange{1}}) map(1:length(i.block)) do I r = blocks(i.indices)[I] return S.indices[first(r)]:S.indices[last(r)] - end, + end ) return BlockIndices(subblocks, subindices) end @@ -201,12 +184,12 @@ function Base.getindex(S::BlockIndices, i::BlockSlice{<:BlockVector{<:BlockIndex subblocks = mortar( map(blocks(i.block)) do br return S.blocks[Int(Block(br))][only(br.indices)] - end, + end ) subindices = mortar( map(blocks(i.block)) do br - S.indices[br] - end, + return S.indices[br] + end ) return BlockIndices(subblocks, subindices) end @@ -273,7 +256,7 @@ const SubBlockSliceCollection = Union{ # ``` function Base.getindex( a::BlockVector{<:BlockIndex{1}, <:AbstractVector{<:BlockIndexRange{1}}}, - I::BlockSlice{<:Block{1}}, + I::BlockSlice{<:Block{1}} ) # Check that the block slice corresponds to the correct block. @assert I.indices == only(axes(a))[Block(I)] @@ -439,7 +422,7 @@ end function blockrange( axis::AbstractUnitRange, - r::BlockVector{<:BlockIndex{1}, <:AbstractVector{<:BlockIndexRange{1}}}, + r::BlockVector{<:BlockIndex{1}, <:AbstractVector{<:BlockIndexRange{1}}} ) return map(Block, blocks(r)) end @@ -465,14 +448,14 @@ end function blockrange( axis::AbstractUnitRange, - r::BlockVector{<:BlockIndex{1}, <:AbstractVector{<:BlockIndexVector}}, + r::BlockVector{<:BlockIndex{1}, <:AbstractVector{<:BlockIndexVector}} ) return map(Block, blocks(r)) end function blockrange( axis::AbstractUnitRange, - r::BlockVector{<:GenericBlockIndex{1}, <:AbstractVector{<:BlockIndexVector}}, + r::BlockVector{<:GenericBlockIndex{1}, <:AbstractVector{<:BlockIndexVector}} ) return map(Block, blocks(r)) end @@ -521,7 +504,7 @@ end function blockindices( a::AbstractUnitRange, b::Block, - r::BlockVector{<:BlockIndex{1}, <:AbstractVector{<:BlockIndexRange{1}}}, + r::BlockVector{<:BlockIndex{1}, <:AbstractVector{<:BlockIndexRange{1}}} ) # TODO: Change to iterate over `BlockRange(r)` # once https://github.com/JuliaArrays/BlockArrays.jl/issues/404 @@ -563,8 +546,8 @@ function subblocks(axes::Tuple, subaxes::Tuple, block::Block) @assert length(axes) == length(subaxes) return BlockRange( ntuple(length(axes)) do dim - findblocks(subaxes[dim], axes[dim][Tuple(block)[dim]]) - end, + return findblocks(subaxes[dim], axes[dim][Tuple(block)[dim]]) + end ) end @@ -663,8 +646,8 @@ end # SVD additions # ------------- -using LinearAlgebra: Algorithm using BlockArrays: BlockedMatrix +using LinearAlgebra: Algorithm # svd first calls `eigencopy_oftype` to create something that can be in-place SVD'd # Here, we hijack this system to determine if there is any structure we can exploit diff --git a/src/BlockArraysExtensions/blockedunitrange.jl b/src/BlockArraysExtensions/blockedunitrange.jl index 6ad7080..c410b63 100644 --- a/src/BlockArraysExtensions/blockedunitrange.jl +++ b/src/BlockArraysExtensions/blockedunitrange.jl @@ -1,21 +1,6 @@ -using BlockArrays: - BlockArrays, - AbstractBlockedUnitRange, - AbstractBlockVector, - Block, - BlockIndex, - BlockIndexRange, - BlockRange, - BlockSlice, - BlockVector, - block, - blockedrange, - blockfirsts, - blockindex, - blocklengths, - findblock, - findblockindex, - mortar +using BlockArrays: BlockArrays, AbstractBlockVector, AbstractBlockedUnitRange, Block, + BlockIndex, BlockIndexRange, BlockRange, BlockSlice, BlockVector, block, blockedrange, + blockfirsts, blockindex, blocklengths, findblock, findblockindex, mortar # Get the axes of each block of a block array. function eachblockaxes(a::AbstractArray) @@ -150,7 +135,8 @@ end # TODO: Make a special definition for `BlockedVector{<:Block{1}}` in order # to merge blocks. function blockedunitrange_getindices( - a::AbstractBlockedUnitRange, indices::AbstractVector{<:Union{Block{1}, BlockIndexRange{1}}} + a::AbstractBlockedUnitRange, + indices::AbstractVector{<:Union{Block{1}, BlockIndexRange{1}}} ) # Without converting `indices` to `Vector`, # mapping `indices` outputs a `BlockVector` @@ -166,7 +152,7 @@ end function blockedunitrange_getindices( a::AbstractBlockedUnitRange, - indices::BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange{1}}}, + indices::BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange{1}}} ) return mortar(map(b -> a[b], blocks(indices))) end @@ -207,7 +193,7 @@ function to_blockindices(a::AbstractBlockedUnitRange{<:Integer}, I::UnitRange{<: bi_last = findblockindex(a, last(r)) @assert block(bi_first) == block(bi_last) return block(bi_first)[blockindex(bi_first):blockindex(bi_last)] - end, + end ) end @@ -314,7 +300,8 @@ _getindex(a::Block{N}, b::Vararg{AbstractVector, N}) where {N} = BlockIndexVecto # Fix ambiguity. _getindex(a::Block{0}) = a[] -struct BlockIndexVector{N, BT, I <: NTuple{N, AbstractVector}, TB <: Integer} <: AbstractArray{BT, N} +struct BlockIndexVector{N, BT, I <: NTuple{N, AbstractVector}, TB <: Integer} <: + AbstractArray{BT, N} block::Block{N, TB} indices::I function BlockIndexVector{N, BT}( @@ -358,17 +345,24 @@ function Base.getindex(b::AbstractBlockedUnitRange, Kkr::BlockIndexVector{1}) end using ArrayLayouts: LayoutArray -@propagate_inbounds Base.getindex(b::AbstractArray{T, N}, K::BlockIndexVector{N}) where {T, N} = b[ +@propagate_inbounds Base.getindex( + b::AbstractArray{T, N}, + K::BlockIndexVector{N} +) where {T, N} = b[ block( K ), ][K.indices...] -@propagate_inbounds Base.getindex(b::LayoutArray{T, N}, K::BlockIndexVector{N}) where {T, N} = b[ +@propagate_inbounds Base.getindex( + b::LayoutArray{T, N}, + K::BlockIndexVector{N} +) where {T, N} = b[ block( K ), ][K.indices...] -@propagate_inbounds Base.getindex(b::LayoutArray{T, 1}, K::BlockIndexVector{1}) where {T} = b[ +@propagate_inbounds Base.getindex(b::LayoutArray{T, 1}, K::BlockIndexVector{1}) where {T} = + b[ block( K ), @@ -376,7 +370,7 @@ using ArrayLayouts: LayoutArray function blockedunitrange_getindices( a::AbstractBlockedUnitRange, - indices::BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, + indices::BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexVector{1}}} ) blks = map(b -> a[b], blocks(indices)) # Preserve any extra structure in the axes, like a @@ -386,7 +380,7 @@ function blockedunitrange_getindices( end function blockedunitrange_getindices( a::AbstractBlockedUnitRange, - indices::BlockVector{<:GenericBlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, + indices::BlockVector{<:GenericBlockIndex{1}, <:Vector{<:BlockIndexVector{1}}} ) blks = map(b -> a[b], blocks(indices)) # Preserve any extra structure in the axes, like a diff --git a/src/BlockArraysExtensions/blockrange.jl b/src/BlockArraysExtensions/blockrange.jl index 21f8a08..cc6551a 100644 --- a/src/BlockArraysExtensions/blockrange.jl +++ b/src/BlockArraysExtensions/blockrange.jl @@ -25,7 +25,8 @@ Base.axes(r::BlockUnitRange) = (blockrange(eachblockaxis(r)),) Base.axes1(r::BlockUnitRange) = blockrange(eachblockaxis(r)) using BlockArrays: BlockedOneTo -const BlockOneTo{T <: Integer, B, CS, R <: BlockedOneTo{T, CS}} = BlockUnitRange{T, B, CS, R} +const BlockOneTo{T <: Integer, B, CS, R <: BlockedOneTo{T, CS}} = + BlockUnitRange{T, B, CS, R} Base.axes(S::Base.Slice{<:BlockOneTo}) = (S.indices,) Base.axes1(S::Base.Slice{<:BlockOneTo}) = S.indices Base.unsafe_indices(S::Base.Slice{<:BlockOneTo}) = (S.indices,) diff --git a/src/abstractblocksparsearray/abstractblocksparsearray.jl b/src/abstractblocksparsearray/abstractblocksparsearray.jl index 8f83391..495780d 100644 --- a/src/abstractblocksparsearray/abstractblocksparsearray.jl +++ b/src/abstractblocksparsearray/abstractblocksparsearray.jl @@ -84,8 +84,8 @@ function Base.setindex!( if size(value) ≠ blocksize throw( DimensionMismatch( - "Trying to set block $(Block(Int.(I)...)), which has a size $blocksize, with data of size $(size(value)).", - ), + "Trying to set block $(Block(Int.(I)...)), which has a size $blocksize, with data of size $(size(value))." + ) ) end if isstored(a, I...) @@ -115,7 +115,10 @@ end block_to_string(b, s) = string(join(map(string, b), '×'), "-blocked ", dims_to_string(s)) using TypeParameterAccessors: type_parameters, unspecify_type_parameters -function concretetype_to_string_truncated(type::Type; param_truncation_length = typemax(Int)) +function concretetype_to_string_truncated( + type::Type; + param_truncation_length = typemax(Int) + ) isconcretetype(type) || throw(ArgumentError("Type must be concrete.")) alias = Base.make_typealias(type) base_type, params = if isnothing(alias) diff --git a/src/abstractblocksparsearray/arraylayouts.jl b/src/abstractblocksparsearray/arraylayouts.jl index fd3079d..5b6e80a 100644 --- a/src/abstractblocksparsearray/arraylayouts.jl +++ b/src/abstractblocksparsearray/arraylayouts.jl @@ -33,7 +33,7 @@ function Base.similar( C, }, elt::Type, - axes, + axes ) where {BlockLayoutA, BlockLayoutB, LayoutC, T, A, B, C} # TODO: Consider using this instead: diff --git a/src/abstractblocksparsearray/broadcast.jl b/src/abstractblocksparsearray/broadcast.jl index 8f81aed..318f515 100644 --- a/src/abstractblocksparsearray/broadcast.jl +++ b/src/abstractblocksparsearray/broadcast.jl @@ -1,5 +1,5 @@ -using BlockArrays: AbstractBlockedUnitRange, BlockSlice using Base.Broadcast: BroadcastStyle +using BlockArrays: AbstractBlockedUnitRange, BlockSlice function Base.Broadcast.BroadcastStyle(arraytype::Type{<:AnyAbstractBlockSparseArray}) return BlockSparseArrayStyle(BroadcastStyle(blocktype(arraytype))) @@ -14,7 +14,7 @@ function Base.Broadcast.BroadcastStyle( <:AbstractBlockSparseArray, <:Tuple{BlockSlice{<:Any, <:Any, <:AbstractBlockedUnitRange}, Vararg{Any}}, }, - }, + } ) return BlockSparseArrayStyle{ndims(arraytype)}() end @@ -30,7 +30,7 @@ function Base.Broadcast.BroadcastStyle( Vararg{Any}, }, }, - }, + } ) return BlockSparseArrayStyle{ndims(arraytype)}() end @@ -42,7 +42,7 @@ function Base.Broadcast.BroadcastStyle( <:AbstractBlockSparseArray, <:Tuple{Any, BlockSlice{<:Any, <:Any, <:AbstractBlockedUnitRange}, Vararg{Any}}, }, - }, + } ) return BlockSparseArrayStyle{ndims(arraytype)}() end @@ -54,12 +54,15 @@ function Base.copyto!(dest::AnyAbstractBlockSparseArray, bc::Broadcasted) return copyto!_blocksparse(dest, bc) end function Base.copyto!( - dest::AnyAbstractBlockSparseArray, bc::Broadcasted{<:Base.Broadcast.AbstractArrayStyle{0}} + dest::AnyAbstractBlockSparseArray, + bc::Broadcasted{<:Base.Broadcast.AbstractArrayStyle{0}} ) return copyto!_blocksparse(dest, bc) end function Base.copyto!( - dest::AnyAbstractBlockSparseArray{<:Any, N}, bc::Broadcasted{<:BlockSparseArrayStyle{N}} + dest::AnyAbstractBlockSparseArray{<:Any, N}, bc::Broadcasted{ + <:BlockSparseArrayStyle{N}, + } ) where {N} return copyto!_blocksparse(dest, bc) end diff --git a/src/abstractblocksparsearray/map.jl b/src/abstractblocksparsearray/map.jl index 671355f..acff521 100644 --- a/src/abstractblocksparsearray/map.jl +++ b/src/abstractblocksparsearray/map.jl @@ -7,7 +7,12 @@ using LinearAlgebra: Adjoint, Transpose # If the blocking of the slice doesn't match the blocking of the # parent array, reblock according to the blocking of the parent array. function reblock( - a::SubArray{<:Any, <:Any, <:AbstractBlockSparseArray, <:Tuple{Vararg{AbstractUnitRange}}} + a::SubArray{ + <:Any, + <:Any, + <:AbstractBlockSparseArray, + <:Tuple{Vararg{AbstractUnitRange}}, + } ) # TODO: This relies on the behavior that slicing a block sparse # array with a UnitRange inherits the blocking of the underlying @@ -30,7 +35,7 @@ function reblock( <:Any, <:AbstractBlockSparseArray, <:Tuple{Vararg{BlockIndices{<:AbstractBlockVector{<:Block{1}}}}}, - }, + } ) # Remove the blocking. return @view parent(a)[map(I -> Vector(I.blocks), parentindices(a))...] diff --git a/src/abstractblocksparsearray/sparsearrayinterface.jl b/src/abstractblocksparsearray/sparsearrayinterface.jl index 54a0fc7..e51adda 100644 --- a/src/abstractblocksparsearray/sparsearrayinterface.jl +++ b/src/abstractblocksparsearray/sparsearrayinterface.jl @@ -17,7 +17,8 @@ function Base.keys(s::BlockSparseStorage) block_axes = axes(blocks(s.array)[I]) blockindices = Block(Tuple(I))[block_axes...] return Iterators.map( - blockindex -> blockindex_to_cartesianindex(s.array, blockindex), blockindices + blockindex -> blockindex_to_cartesianindex(s.array, blockindex), + blockindices ) end return Iterators.flatten(stored_blockindices) diff --git a/src/abstractblocksparsearray/unblockedsubarray.jl b/src/abstractblocksparsearray/unblockedsubarray.jl index 63cbc64..6ed0aed 100644 --- a/src/abstractblocksparsearray/unblockedsubarray.jl +++ b/src/abstractblocksparsearray/unblockedsubarray.jl @@ -71,7 +71,7 @@ function Base.map!( f, a_dest, a_src1, - a_src_rest..., + a_src_rest... ) end @@ -82,7 +82,7 @@ function Base.map!( f, a_dest::GPUArraysCore.AnyGPUArray, a_src1::UnblockedSubArray, - a_src_rest::UnblockedSubArray..., + a_src_rest::UnblockedSubArray... ) a_dest_cpu = adapt(Array, a_dest) a_srcs_cpu = map(adapt(Array), (a_src1, a_src_rest...)) diff --git a/src/abstractblocksparsearray/views.jl b/src/abstractblocksparsearray/views.jl index 7c45f0a..fc212d9 100644 --- a/src/abstractblocksparsearray/views.jl +++ b/src/abstractblocksparsearray/views.jl @@ -1,12 +1,5 @@ -using BlockArrays: - AbstractBlockedUnitRange, - BlockArrays, - Block, - BlockIndexRange, - BlockedVector, - blocklength, - blocksize, - viewblock +using BlockArrays: BlockArrays, AbstractBlockedUnitRange, Block, BlockIndexRange, + BlockedVector, blocklength, blocksize, viewblock using FunctionImplementations: style # This splits `BlockIndexRange{N}` into @@ -36,23 +29,30 @@ end # which don't handle subslices of blocks properly. function Base.view( a::SubArray{ - <:Any, N, <:AnyAbstractBlockSparseArray, <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, + <:Any, N, <:AnyAbstractBlockSparseArray, + <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, }, - I::Block{N}, + I::Block{N} ) where {N} return style(a)(view)(a, I) end function Base.view( a::SubArray{ - <:Any, N, <:AnyAbstractBlockSparseArray, <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, + <:Any, N, <:AnyAbstractBlockSparseArray, + <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, }, - I::Vararg{Block{1}, N}, + I::Vararg{Block{1}, N} ) where {N} return style(a)(view)(a, I...) end function Base.view( - V::SubArray{<:Any, 1, <:AnyAbstractBlockSparseArray, <:Tuple{BlockSlice{<:BlockRange{1}}}}, - I::Block{1}, + V::SubArray{ + <:Any, + 1, + <:AnyAbstractBlockSparseArray, + <:Tuple{BlockSlice{<:BlockRange{1}}}, + }, + I::Block{1} ) return style(a)(view)(a, I) end @@ -100,7 +100,7 @@ to_block_indices(I::BlockIndexVector{1}) = only(I.indices) function Base.view( a::AbstractBlockSparseArray{<:Any, N}, - I::Vararg{Union{Block{1}, BlockIndexRange{1}, BlockIndexVector}, N}, + I::Vararg{Union{Block{1}, BlockIndexRange{1}, BlockIndexVector}, N} ) where {N} return @views a[to_block.(I)...][to_block_indices.(I)...] end @@ -112,7 +112,7 @@ function Base.view( end function Base.view( a::SubArray{T, N, <:AbstractBlockSparseArray{T, N}}, - I::Vararg{Union{Block{1}, BlockIndexRange{1}, BlockIndexVector}, N}, + I::Vararg{Union{Block{1}, BlockIndexRange{1}, BlockIndexVector}, N} ) where {T, N} return @views a[to_block.(I)...][to_block_indices.(I)...] end @@ -130,7 +130,7 @@ function Base.view( <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Union{BlockSliceCollection, SubBlockSliceCollection}, N}}, }, - block::Union{Block{N}, BlockIndexRange{N}}, + block::Union{Block{N}, BlockIndexRange{N}} ) where {T, N} return viewblock(a, block) end @@ -144,7 +144,7 @@ function Base.view( <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Union{Base.Slice, BlockSlice{<:BlockRange{1}}}, N}}, }, - block::Block{N}, + block::Block{N} ) where {T, N} return viewblock(a, block) end @@ -156,7 +156,7 @@ function Base.view( <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Union{BlockSliceCollection, SubBlockSliceCollection}, N}}, }, - block::Vararg{Union{Block{1}, BlockIndexRange{1}}, N}, + block::Vararg{Union{Block{1}, BlockIndexRange{1}}, N} ) where {T, N} return viewblock(a, block...) end @@ -167,7 +167,7 @@ function BlockArrays.viewblock( <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Union{BlockSliceCollection, SubBlockSliceCollection}, N}}, }, - block::Union{Block{N}, BlockIndexRange{N}, BlockIndexVector{N}}, + block::Union{Block{N}, BlockIndexRange{N}, BlockIndexVector{N}} ) where {T, N} return viewblock(a, to_tuple(block)...) end @@ -175,18 +175,20 @@ end # Fixes ambiguity error with `AnyAbstractBlockSparseArray` definition. function Base.view( a::SubArray{ - T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, + T, N, <:AbstractBlockSparseArray{T, N}, + <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, }, - block::Block{N}, + block::Block{N} ) where {T, N} return viewblock(a, block) end # Fixes ambiguity error with `AnyAbstractBlockSparseArray` definition. function Base.view( a::SubArray{ - T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, + T, N, <:AbstractBlockSparseArray{T, N}, + <:Tuple{Vararg{BlockSlice{<:BlockRange{1}}, N}}, }, - block::Vararg{Block{1}, N}, + block::Vararg{Block{1}, N} ) where {T, N} return viewblock(a, block...) end @@ -196,7 +198,7 @@ end # which both include `Base.Slice`. function Base.view( a::SubArray{T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Base.Slice, N}}}, - block::Block{N}, + block::Block{N} ) where {T, N} return viewblock(a, block) end @@ -217,8 +219,13 @@ end # in `blocksparsearrayinterface/blocksparsearrayinterface.jl`. # TODO: Define `style(a)(viewblock)`. function BlockArrays.viewblock( - a::SubArray{T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{BlockSliceCollection, N}}}, - block::Vararg{Block{1}, N}, + a::SubArray{ + T, + N, + <:AbstractBlockSparseArray{T, N}, + <:Tuple{Vararg{BlockSliceCollection, N}}, + }, + block::Vararg{Block{1}, N} ) where {T, N} return viewblock_blockslice(a, block...) end @@ -228,27 +235,30 @@ end # which both include `Base.Slice`. function BlockArrays.viewblock( a::SubArray{T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Base.Slice, N}}}, - block::Vararg{Block{1}, N}, + block::Vararg{Block{1}, N} ) where {T, N} return viewblock_blockslice(a, block...) end function to_blockindexrange( - a::BlockSlice{<:BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange{1}}}}, I::Block{1} + a::BlockSlice{<:BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange{1}}}}, + I::Block{1} ) # TODO: Ideally we would just use `a.blocks[I]` but that doesn't # work right now. return blocks(a.block)[Int(I)] end function to_blockindexrange( - a::BlockIndices{<:BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange}}}, I::Block{1} + a::BlockIndices{<:BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange}}}, + I::Block{1} ) # TODO: Ideally we would just use `a.blocks[I]` but that doesn't # work right now. return blocks(a.blocks)[Int(I)] end function to_blockindexrange( - a::BlockIndices{<:BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexVector}}}, I::Block{1} + a::BlockIndices{<:BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexVector}}}, + I::Block{1} ) # TODO: Ideally we would just use `a.blocks[I]` but that doesn't # work right now. @@ -256,7 +266,7 @@ function to_blockindexrange( end function to_blockindexrange( a::BlockIndices{<:BlockVector{<:GenericBlockIndex{1}, <:Vector{<:BlockIndexVector}}}, - I::Block{1}, + I::Block{1} ) # TODO: Ideally we would just use `a.blocks[I]` but that doesn't # work right now. @@ -276,7 +286,7 @@ function BlockArrays.viewblock( <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Union{BlockSliceCollection, SubBlockSliceCollection}, N}}, }, - block::Vararg{Block{1}, N}, + block::Vararg{Block{1}, N} ) where {T, N} brs = ntuple(dim -> to_blockindexrange(parentindices(a)[dim], block[dim]), ndims(a)) return @view parent(a)[brs...] @@ -290,7 +300,7 @@ function BlockArrays.viewblock( <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{Union{BlockSliceCollection, SubBlockSliceCollection}, N}}, }, - block::Vararg{BlockIndexRange{1}, N}, + block::Vararg{BlockIndexRange{1}, N} ) where {T, N} return view(viewblock(a, Block.(block)...), map(b -> only(b.indices), block)...) end @@ -299,13 +309,18 @@ function Base.view( a::SubArray{ T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{SubBlockSliceCollection, N}}, }, - block::Union{Block{N}, BlockIndexRange{N}}, + block::Union{Block{N}, BlockIndexRange{N}} ) where {T, N} return viewblock(a, block) end function Base.view( - a::SubArray{T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{BlockIndexRangeSlice, N}}}, - block::Union{Block{N}, BlockIndexRange{N}}, + a::SubArray{ + T, + N, + <:AbstractBlockSparseArray{T, N}, + <:Tuple{Vararg{BlockIndexRangeSlice, N}}, + }, + block::Union{Block{N}, BlockIndexRange{N}} ) where {T, N} return viewblock(a, block) end @@ -313,7 +328,7 @@ function Base.view( a::SubArray{ T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{SubBlockSliceCollection, N}}, }, - block::Vararg{Union{Block{1}, BlockIndexRange{1}, BlockIndexVector}, N}, + block::Vararg{Union{Block{1}, BlockIndexRange{1}, BlockIndexVector}, N} ) where {T, N} return viewblock(a, block...) end @@ -322,7 +337,7 @@ function Base.view( a::SubArray{ T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{SubBlockSliceCollection, N}}, }, - block::Vararg{Block{1}, N}, + block::Vararg{Block{1}, N} ) where {T, N} return viewblock(a, block...) end @@ -330,7 +345,7 @@ function BlockArrays.viewblock( a::SubArray{ T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{SubBlockSliceCollection, N}}, }, - block::Union{Block{N}, BlockIndexRange{N}}, + block::Union{Block{N}, BlockIndexRange{N}} ) where {T, N} return viewblock(a, to_tuple(block)...) end @@ -342,7 +357,7 @@ function blockedslice_blocks(x::Base.Slice) return mortar( map(BlockRange(x.indices)) do b return BlockIndexRange(b, Base.Slice(Base.axes1(x.indices[b]))) - end, + end ) end @@ -351,7 +366,7 @@ function BlockArrays.viewblock( a::SubArray{ T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{SubBlockSliceCollection, N}}, }, - I::Vararg{Block{1}, N}, + I::Vararg{Block{1}, N} ) where {T, N} # TODO: Use `reindex`, `to_indices`, etc. brs = ntuple(ndims(a)) do dim @@ -368,7 +383,7 @@ function BlockArrays.viewblock( a::SubArray{ T, N, <:AbstractBlockSparseArray{T, N}, <:Tuple{Vararg{SubBlockSliceCollection, N}}, }, - block::Vararg{BlockIndexRange{1}, N}, + block::Vararg{BlockIndexRange{1}, N} ) where {T, N} return view(viewblock(a, Block.(block)...), map(b -> only(b.indices), block)...) end @@ -380,8 +395,13 @@ for (f, F) in ((:adjoint, :Adjoint), (:transpose, :Transpose)) return $f(view(parent(A), b)) end - Base.view(A::$F{<:Any, <:AbstractBlockSparseMatrix}, b::Block{2}) = view(A, Tuple(b)...) - function Base.view(A::$F{<:Any, <:AbstractBlockSparseMatrix}, b1::Block{1}, b2::Block{1}) + Base.view(A::$F{<:Any, <:AbstractBlockSparseMatrix}, b::Block{2}) = + view(A, Tuple(b)...) + function Base.view( + A::$F{<:Any, <:AbstractBlockSparseMatrix}, + b1::Block{1}, + b2::Block{1} + ) return $f(view(parent(A), b2, b1)) end end diff --git a/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl b/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl index c726b56..06fae49 100644 --- a/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl +++ b/src/abstractblocksparsearray/wrappedabstractblocksparsearray.jl @@ -1,14 +1,7 @@ using Adapt: Adapt, WrappedArray, adapt using ArrayLayouts: ArrayLayouts -using BlockArrays: - BlockArrays, - AbstractBlockVector, - AbstractBlockedUnitRange, - BlockIndexRange, - BlockRange, - blockedrange, - mortar, - unblock +using BlockArrays: BlockArrays, AbstractBlockVector, AbstractBlockedUnitRange, + BlockIndexRange, BlockRange, blockedrange, mortar, unblock using FunctionImplementations: FunctionImplementations, ImplementationStyle, style, zero! using GPUArraysCore: @allowscalar using SplitApplyCombine: groupcount @@ -28,7 +21,9 @@ const AnyAbstractBlockSparseVecOrMat{T, N} = Union{ AnyAbstractBlockSparseVector{T}, AnyAbstractBlockSparseMatrix{T}, } -function FunctionImplementations.ImplementationStyle(arrayt::Type{<:AnyAbstractBlockSparseArray}) +function FunctionImplementations.ImplementationStyle( + arrayt::Type{<:AnyAbstractBlockSparseArray} + ) return BlockSparseArrayImplementationStyle() end @@ -47,7 +42,8 @@ end # Fix ambiguity error with Base for logical indexing in Julia 1.10. # TODO: Delete this once we drop support for Julia 1.10. function Base.to_indices( - a::AnyAbstractBlockSparseArray, inds, I::Union{Tuple{BitArray{N}}, Tuple{Array{Bool, N}}} + a::AnyAbstractBlockSparseArray, inds, + I::Union{Tuple{BitArray{N}}, Tuple{Array{Bool, N}}} ) where {N} return style(a)(to_indices)(a, inds, I) end @@ -64,7 +60,7 @@ end function Base.to_indices( a::AnyAbstractBlockSparseArray, inds, - I::Tuple{AbstractBlockVector{<:Block{1}}, Vararg{Any}}, + I::Tuple{AbstractBlockVector{<:Block{1}}, Vararg{Any}} ) return style(a)(to_indices)(a, inds, I) end @@ -73,7 +69,7 @@ end function Base.to_indices( a::AnyAbstractBlockSparseArray, inds, - I::Tuple{BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange{1}}}, Vararg{Any}}, + I::Tuple{BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexRange{1}}}, Vararg{Any}} ) return style(a)(to_indices)(a, inds, I) end @@ -82,28 +78,33 @@ end function Base.to_indices( a::AnyAbstractBlockSparseArray, inds, - I::Tuple{BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, Vararg{Any}}, + I::Tuple{BlockVector{<:BlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, Vararg{Any}} ) return style(a)(to_indices)(a, inds, I) end function Base.to_indices( a::AnyAbstractBlockSparseArray, inds, - I::Tuple{BlockVector{<:GenericBlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, Vararg{Any}}, + I::Tuple{ + BlockVector{<:GenericBlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, + Vararg{Any}, + } ) return style(a)(to_indices)(a, inds, I) end # a[[Block(1)[1:2], Block(2)[1:2]], [Block(1)[1:2], Block(2)[1:2]]] function Base.to_indices( - a::AnyAbstractBlockSparseArray, inds, I::Tuple{Vector{<:BlockIndexRange{1}}, Vararg{Any}} + a::AnyAbstractBlockSparseArray, inds, + I::Tuple{Vector{<:BlockIndexRange{1}}, Vararg{Any}} ) return to_indices(a, inds, (mortar(I[1]), Base.tail(I)...)) end # a[[Block(1)[[1, 2]], Block(2)[[1, 2]]], [Block(1)[[1, 2]], Block(2)[[1, 2]]]] function Base.to_indices( - a::AnyAbstractBlockSparseArray, inds, I::Tuple{Vector{<:BlockIndexVector{1}}, Vararg{Any}} + a::AnyAbstractBlockSparseArray, inds, + I::Tuple{Vector{<:BlockIndexVector{1}}, Vararg{Any}} ) return to_indices(a, inds, (mortar(I[1]), Base.tail(I)...)) end @@ -163,7 +164,10 @@ function Base.isassigned(a::AnyAbstractBlockSparseArray{<:Any, 0}) return isassigned(blocks(a)) end -function Base.isassigned(a::AnyAbstractBlockSparseArray{<:Any, N}, index::Block{N}) where {N} +function Base.isassigned( + a::AnyAbstractBlockSparseArray{<:Any, N}, + index::Block{N} + ) where {N} return isassigned(a, Tuple(index)...) end @@ -198,14 +202,15 @@ end # Needed by `BlockArrays` matrix multiplication interface function Base.similar( arraytype::Type{<:AnyAbstractBlockSparseArray}, - axes::Tuple{Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{Vararg{AbstractUnitRange{<:Integer}}} ) return similar(arraytype, eltype(arraytype), axes) end # Fixes ambiguity error. function Base.similar( - arraytype::Type{<:AnyAbstractBlockSparseArray}, axes::Tuple{Base.OneTo, Vararg{Base.OneTo}} + arraytype::Type{<:AnyAbstractBlockSparseArray}, + axes::Tuple{Base.OneTo, Vararg{Base.OneTo}} ) return similar(arraytype, eltype(arraytype), axes) end @@ -216,7 +221,7 @@ end # Delete once we drop support for older versions of Julia. function Base.similar( arraytype::Type{<:AnyAbstractBlockSparseArray}, - axes::Tuple{AbstractUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{AbstractUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}} ) return similar(arraytype, eltype(arraytype), axes) end @@ -224,7 +229,7 @@ end # Fixes ambiguity error with `BlockArrays`. function Base.similar( arraytype::Type{<:AnyAbstractBlockSparseArray}, - axes::Tuple{AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}} ) return similar(arraytype, eltype(arraytype), axes) end @@ -236,7 +241,7 @@ function Base.similar( AbstractUnitRange{<:Integer}, AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}, - }, + } ) return similar(arraytype, eltype(arraytype), axes) end @@ -244,7 +249,7 @@ end # Needed for disambiguation function Base.similar( arraytype::Type{<:AnyAbstractBlockSparseArray}, - axes::Tuple{Vararg{AbstractBlockedUnitRange{<:Integer}}}, + axes::Tuple{Vararg{AbstractBlockedUnitRange{<:Integer}}} ) return similar(arraytype, eltype(arraytype), axes) end @@ -253,7 +258,8 @@ function blocksparse_similar(a, elt::Type, axes::Tuple) ndims = length(axes) # TODO: Define a version of `similartype` that catches the case # where the output isn't concrete and returns an `AbstractArray`. - blockt = Base.promote_op(similar, blocktype(a), Type{elt}, Tuple{blockaxistype.(axes)...}) + blockt = + Base.promote_op(similar, blocktype(a), Type{elt}, Tuple{blockaxistype.(axes)...}) blockt′ = !isconcretetype(blockt) ? AbstractArray{elt, ndims} : blockt return BlockSparseArray{elt, ndims, blockt′}(undef, axes) end @@ -301,7 +307,7 @@ end function Base.similar( arraytype::Type{<:AnyAbstractBlockSparseArray}, elt::Type, - axes::Tuple{Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{Vararg{AbstractUnitRange{<:Integer}}} ) return ImplementationStyle(arraytype)(similar)(arraytype, elt, axes) end @@ -309,7 +315,7 @@ end function Base.similar( a::AnyAbstractBlockSparseArray, elt::Type, - axes::Tuple{Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{Vararg{AbstractUnitRange{<:Integer}}} ) return style(a)(similar)(a, elt, axes) end @@ -325,7 +331,7 @@ function Base.similar( elt::Type, axes::Tuple{ AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractBlockedUnitRange{<:Integer}}, - }, + } ) return style(a)(similar)(a, elt, axes) end @@ -334,7 +340,7 @@ end function Base.similar( a::AnyAbstractBlockSparseArray, elt::Type, - axes::Tuple{AbstractUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{AbstractUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}} ) return style(a)(similar)(a, elt, axes) end @@ -343,7 +349,7 @@ end function Base.similar( a::AnyAbstractBlockSparseArray, elt::Type, - axes::Tuple{AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}} ) return style(a)(similar)(a, elt, axes) end @@ -352,7 +358,7 @@ function Base.similar(a::AnyAbstractBlockSparseArray, elt::Type) end function Base.similar( a::AnyAbstractBlockSparseArray, - axes::Tuple{AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}}, + axes::Tuple{AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}} ) return style(a)(similar)(a, eltype(a), axes) end @@ -365,7 +371,7 @@ function Base.similar( AbstractUnitRange{<:Integer}, AbstractBlockedUnitRange{<:Integer}, Vararg{AbstractUnitRange{<:Integer}}, - }, + } ) return style(a)(similar)(a, elt, axes) end diff --git a/src/blocksparsearray/blocksparsearray.jl b/src/blocksparsearray/blocksparsearray.jl index 0768ecb..0bdae30 100644 --- a/src/blocksparsearray/blocksparsearray.jl +++ b/src/blocksparsearray/blocksparsearray.jl @@ -1,11 +1,5 @@ -using BlockArrays: - BlockArrays, - Block, - BlockedUnitRange, - UndefBlocksInitializer, - blockedrange, - blocklength, - undef_blocks +using BlockArrays: BlockArrays, Block, BlockedUnitRange, UndefBlocksInitializer, + blockedrange, blocklength, undef_blocks using Dictionaries: Dictionary using SparseArraysBase: SparseArrayDOK, Unstored using TypeParameterAccessors: similartype @@ -33,14 +27,14 @@ function SparseArraysBase.SparseArrayDOK{T, N}( end function SparseArraysBase.SparseArrayDOK{T, N}( ::UndefBlocksInitializer, - dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}}, + dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}} ) where {T, N} return SparseArrayDOK{T, N}(undef_blocks, blockedrange.(dims)) end function SparseArraysBase.SparseArrayDOK{T, N}( ::UndefBlocksInitializer, dim1::AbstractVector{<:Integer}, - dim_rest::AbstractVector{<:Integer}..., + dim_rest::AbstractVector{<:Integer}... ) where {T, N} return SparseArrayDOK{T, N}(undef_blocks, (dim1, dim_rest...)) end @@ -57,14 +51,14 @@ function SparseArraysBase.SparseArrayDOK{T}( end function SparseArraysBase.SparseArrayDOK{T}( ::UndefBlocksInitializer, - dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}}, + dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}} ) where {T} return SparseArrayDOK{T}(undef_blocks, blockedrange.(dims)) end function SparseArraysBase.SparseArrayDOK{T}( ::UndefBlocksInitializer, dim1::AbstractVector{<:Integer}, - dim_rest::AbstractVector{<:Integer}..., + dim_rest::AbstractVector{<:Integer}... ) where {T} return SparseArrayDOK{T}(undef_blocks, (dim1, dim_rest...)) end @@ -82,7 +76,7 @@ struct BlockSparseArray{ axes::Axes global @inline function _BlockSparseArray( blocks::AbstractArray{<:AbstractArray{T, N}, N}, - axes::Tuple{Vararg{AbstractUnitRange{<:Integer}, N}}, + axes::Tuple{Vararg{AbstractUnitRange{<:Integer}, N}} ) where {T, N} Base.require_one_based_indexing(axes...) Base.require_one_based_indexing(blocks) @@ -91,12 +85,22 @@ struct BlockSparseArray{ end # TODO: Can this definition be shortened? -const BlockSparseMatrix{T, A <: AbstractMatrix{T}, Blocks <: AbstractMatrix{A}, Axes <: Tuple{AbstractUnitRange{<:Integer}, AbstractUnitRange{<:Integer}}} = BlockSparseArray{ +const BlockSparseMatrix{ + T, + A <: AbstractMatrix{T}, + Blocks <: AbstractMatrix{A}, + Axes <: Tuple{AbstractUnitRange{<:Integer}, AbstractUnitRange{<:Integer}}, +} = BlockSparseArray{ T, 2, A, Blocks, Axes, } # TODO: Can this definition be shortened? -const BlockSparseVector{T, A <: AbstractVector{T}, Blocks <: AbstractVector{A}, Axes <: Tuple{AbstractUnitRange{<:Integer}}} = BlockSparseArray{ +const BlockSparseVector{ + T, + A <: AbstractVector{T}, + Blocks <: AbstractVector{A}, + Axes <: Tuple{AbstractUnitRange{<:Integer}}, +} = BlockSparseArray{ T, 1, A, Blocks, Axes, } @@ -108,26 +112,26 @@ The block sizes must be commensurate with the blocks of the axes. """ function sparsemortar( blocks::AbstractArray{<:AbstractArray{T, N}, N}, - axes::Tuple{Vararg{AbstractUnitRange{<:Integer}, N}}, + axes::Tuple{Vararg{AbstractUnitRange{<:Integer}, N}} ) where {T, N} return _BlockSparseArray(blocks, axes) end function sparsemortar( blocks::AbstractArray{<:AbstractArray{T, N}, N}, - axes::Vararg{AbstractUnitRange{<:Integer}, N}, + axes::Vararg{AbstractUnitRange{<:Integer}, N} ) where {T, N} return sparsemortar(blocks, axes) end function sparsemortar( blocks::AbstractArray{<:AbstractArray{T, N}, N}, - dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}}, + dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}} ) where {T, N} return sparsemortar(blocks, blockedrange.(dims)) end function sparsemortar( blocks::AbstractArray{<:AbstractArray{T, N}, N}, dim1::AbstractVector{<:Integer}, - dim_rest::AbstractVector{<:Integer}..., + dim_rest::AbstractVector{<:Integer}... ) where {T, N} return sparsemortar(blocks, (dim1, dim_rest...)) end @@ -155,7 +159,7 @@ end function BlockSparseArray{T, N, A}( ::UndefInitializer, - dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}}, + dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}} ) where {T, N, A <: AbstractArray{T, N}} length(dims) == N || throw(ArgumentError("Length of dims doesn't match number of dimensions.")) @@ -165,7 +169,7 @@ end function BlockSparseArray{T, N, A}( ::UndefInitializer, dim1::AbstractVector{<:Integer}, - dim_rest::AbstractVector{<:Integer}..., + dim_rest::AbstractVector{<:Integer}... ) where {T, N, A <: AbstractArray{T, N}} return BlockSparseArray{T, N, A}(undef, (dim1, dim_rest...)) end @@ -205,7 +209,7 @@ end function BlockSparseArray{T, N}( ::UndefInitializer, - dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}}, + dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}} ) where {T, N} return BlockSparseArray{T, N}(undef, blockedrange.(dims)) end @@ -213,14 +217,14 @@ end function BlockSparseArray{T, N}( ::UndefInitializer, dim1::AbstractVector{<:Integer}, - dim_rest::AbstractVector{<:Integer}..., + dim_rest::AbstractVector{<:Integer}... ) where {T, N} return BlockSparseArray{T, N}(undef, (dim1, dim_rest...)) end function BlockSparseArray{T}( ::UndefInitializer, - dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}}, + dims::Tuple{AbstractVector{<:Integer}, Vararg{AbstractVector{<:Integer}}} ) where {T} return BlockSparseArray{T, length(dims)}(undef, dims) end @@ -234,7 +238,7 @@ end function BlockSparseArray{T}( ::UndefInitializer, dim1::AbstractVector{<:Integer}, - dim_rest::AbstractVector{<:Integer}..., + dim_rest::AbstractVector{<:Integer}... ) where {T} return BlockSparseArray{T}(undef, (dim1, dim_rest...)) end diff --git a/src/blocksparsearrayinterface/arraylayouts.jl b/src/blocksparsearrayinterface/arraylayouts.jl index 22d4845..b172d61 100644 --- a/src/blocksparsearrayinterface/arraylayouts.jl +++ b/src/blocksparsearrayinterface/arraylayouts.jl @@ -1,7 +1,7 @@ using ArrayLayouts: ArrayLayouts, Dot, MatMulMatAdd, MatMulVecAdd, MulAdd using BlockArrays: BlockArrays, BlockLayout, muladd! -using SparseArraysBase: SparseLayout using LinearAlgebra: LinearAlgebra, dot, mul! +using SparseArraysBase: SparseLayout const muladd!_blocksparse = blocksparse_style(muladd!) function muladd!_blocksparse( @@ -16,7 +16,7 @@ function ArrayLayouts.materialize!( <:BlockLayout{<:SparseLayout}, <:BlockLayout{<:SparseLayout}, <:BlockLayout{<:SparseLayout}, - }, + } ) muladd!_blocksparse(m.α, m.A, m.B, m.β, m.C) return m.C @@ -26,7 +26,7 @@ function ArrayLayouts.materialize!( <:BlockLayout{<:SparseLayout}, <:BlockLayout{<:SparseLayout}, <:BlockLayout{<:SparseLayout}, - }, + } ) error("Not implemented.") matmul!(m) diff --git a/src/blocksparsearrayinterface/blocksparsearrayinterface.jl b/src/blocksparsearrayinterface/blocksparsearrayinterface.jl index 2bb6e6f..417afb5 100644 --- a/src/blocksparsearrayinterface/blocksparsearrayinterface.jl +++ b/src/blocksparsearrayinterface/blocksparsearrayinterface.jl @@ -1,32 +1,11 @@ using ArrayLayouts: ArrayLayouts -using BlockArrays: - BlockArrays, - AbstractBlockVector, - Block, - BlockIndex, - BlockRange, - BlockSlice, - BlockVector, - BlockedUnitRange, - BlockedVector, - block, - blockcheckbounds, - blockisequal, - blocklengths, - blocklength, - blocks, - findblockindex +using BlockArrays: BlockArrays, AbstractBlockVector, Block, BlockIndex, BlockRange, + BlockSlice, BlockVector, BlockedUnitRange, BlockedVector, block, blockcheckbounds, + blockisequal, blocklength, blocklengths, blocks, findblockindex using FunctionImplementations: FunctionImplementations, permuteddims, zero! using LinearAlgebra: Adjoint, Transpose -using SparseArraysBase: - AbstractSparseArrayImplementationStyle, - getstoredindex, - getunstoredindex, - eachstoredindex, - perm, - iperm, - storedlength, - storedvalues +using SparseArraysBase: AbstractSparseArrayImplementationStyle, eachstoredindex, + getstoredindex, getunstoredindex, iperm, perm, storedlength, storedvalues # Like `SparseArraysBase.eachstoredindex` but # at the block level, i.e. iterates over the @@ -109,14 +88,15 @@ blockstype(a::BlockArray) = blockstype(typeof(a)) blocktype(arraytype::Type{<:BlockArray}) = eltype(blockstype(arraytype)) blocktype(a::BlockArray) = eltype(blocks(a)) -abstract type AbstractBlockSparseArrayImplementationStyle <: AbstractSparseArrayImplementationStyle end +abstract type AbstractBlockSparseArrayImplementationStyle <: +AbstractSparseArrayImplementationStyle end struct BlockSparseArrayImplementationStyle <: AbstractBlockSparseArrayImplementationStyle end const blocksparse_style = BlockSparseArrayImplementationStyle() function FunctionImplementations.ImplementationStyle( style1::AbstractBlockSparseArrayImplementationStyle, - style2::AbstractBlockSparseArrayImplementationStyle, + style2::AbstractBlockSparseArrayImplementationStyle ) return BlockSparseArrayImplementationStyle() end @@ -178,7 +158,7 @@ end function to_indices_blocksparse( a, inds::Tuple{Base.OneTo{<:Integer}, Vararg{Any}}, - I::Tuple{UnitRange{<:Integer}, Vararg{Any}}, + I::Tuple{UnitRange{<:Integer}, Vararg{Any}} ) return (inds[1][I[1]], to_indices(a, Base.tail(inds), Base.tail(I))...) end @@ -197,9 +177,12 @@ function to_indices_blocksparse( a, inds, I::Tuple{ - BlockVector{<:BlockIndex{1}, <:Vector{<:Union{BlockIndexRange{1}, BlockIndexVector{1}}}}, + BlockVector{ + <:BlockIndex{1}, + <:Vector{<:Union{BlockIndexRange{1}, BlockIndexVector{1}}}, + }, Vararg{Any}, - }, + } ) # Index the `inds` by the `BlockIndexRange`/`BlockIndexVector`s on each block # in order to canonicalize the indices and preserve metadata, @@ -209,7 +192,7 @@ function to_indices_blocksparse( b = Block(bi) binds = only(bi.indices) return BlockIndexVector(b, Base.axes1(inds[1][b])[binds]) - end, + end ) I1 = BlockIndices(bs, blockedunitrange_getindices(inds[1], I[1])) return (I1, to_indices(a, Base.tail(inds), Base.tail(I))...) @@ -217,7 +200,10 @@ end function to_indices_blocksparse( a, inds, - I::Tuple{BlockVector{<:GenericBlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, Vararg{Any}}, + I::Tuple{ + BlockVector{<:GenericBlockIndex{1}, <:Vector{<:BlockIndexVector{1}}}, + Vararg{Any}, + } ) I1 = BlockIndices(I[1], blockedunitrange_getindices(inds[1], I[1])) return (I1, to_indices(a, Base.tail(inds), Base.tail(I))...) @@ -364,7 +350,14 @@ struct SparsePermutedDimsArrayBlocks{ array::Array end function blocks_blocksparse(a::PermutedDimsArray) - return SparsePermutedDimsArrayBlocks{eltype(a), ndims(a), blocktype(parent(a)), typeof(a)}(a) + return SparsePermutedDimsArrayBlocks{ + eltype(a), + ndims(a), + blocktype(parent(a)), + typeof(a), + }( + a + ) end function Base.size(a::SparsePermutedDimsArrayBlocks) return _getindices(size(blocks(parent(a.array))), _perm(a.array)) @@ -379,7 +372,7 @@ function SparseArraysBase.getstoredindex( ) where {N} return permuteddims( getstoredindex(blocks(parent(a.array)), _getindices(index, _invperm(a.array))...), - _perm(a.array), + _perm(a.array) ) end function SparseArraysBase.getunstoredindex( @@ -387,13 +380,16 @@ function SparseArraysBase.getunstoredindex( ) where {N} return permuteddims( getunstoredindex(blocks(parent(a.array)), _getindices(index, _invperm(a.array))...), - _perm(a.array), + _perm(a.array) ) end function SparseArraysBase.eachstoredindex( ::IndexCartesian, a::SparsePermutedDimsArrayBlocks ) - return map(I -> _getindices(I, _perm(a.array)), eachstoredindex(blocks(parent(a.array)))) + return map( + I -> _getindices(I, _perm(a.array)), + eachstoredindex(blocks(parent(a.array))) + ) end ## TODO: Define `storedvalues` instead. ## function SparseArraysBase.sparse_storage(a::SparsePermutedDimsArrayBlocks) @@ -408,7 +404,12 @@ blocks_blocksparse(a::Adjoint) = adjoint(blocks(parent(a))) # Represents the array of arrays of a `SubArray` # wrapping a block spare array, i.e. `blocks(array)` where `a` is a `SubArray`. -struct SparseSubArrayBlocks{T, N, BlockType <: AbstractArray{T, N}, Array <: SubArray{T, N}} <: +struct SparseSubArrayBlocks{ + T, + N, + BlockType <: AbstractArray{T, N}, + Array <: SubArray{T, N}, + } <: AbstractSparseArray{BlockType, N} array::Array end @@ -456,7 +457,11 @@ function Base.getindex(a::SparseSubArrayBlocks{<:Any, N}, I::CartesianIndex{N}) return a[Tuple(I)...] end # TODO: Define `setstoredindex!`, `setunstoredindex!` instead. -function Base.setindex!(a::SparseSubArrayBlocks{<:Any, N}, value, I::Vararg{Int, N}) where {N} +function Base.setindex!( + a::SparseSubArrayBlocks{<:Any, N}, + value, + I::Vararg{Int, N} + ) where {N} parent_blocks = @view blocks(parent(a.array))[blockrange(a)...] # TODO: The following line is required to instantiate # uninstantiated blocks, maybe use `@view!` instead, diff --git a/src/blocksparsearrayinterface/broadcast.jl b/src/blocksparsearrayinterface/broadcast.jl index 3e5e6aa..d8d69ed 100644 --- a/src/blocksparsearrayinterface/broadcast.jl +++ b/src/blocksparsearrayinterface/broadcast.jl @@ -1,8 +1,6 @@ -using Base.Broadcast: BroadcastStyle, Broadcasted +using Base.Broadcast: AbstractArrayStyle, BroadcastStyle, Broadcasted using GPUArraysCore: @allowscalar using MapBroadcast: Mapped - -using Base.Broadcast: AbstractArrayStyle abstract type AbstractBlockSparseArrayStyle{N, B <: AbstractArrayStyle{N}} <: AbstractArrayStyle{N} end struct BlockSparseArrayStyle{N, B <: AbstractArrayStyle{N}} <: @@ -25,20 +23,25 @@ function BlockSparseArrayStyle{M, B}(::Val{N}) where {M, B <: AbstractArrayStyle end function blockstyle( - ::AbstractBlockSparseArrayStyle{N, B}, + ::AbstractBlockSparseArrayStyle{N, B} ) where {N, B <: Base.Broadcast.AbstractArrayStyle{N}} return B() end function Base.Broadcast.BroadcastStyle( style1::AbstractBlockSparseArrayStyle, - style2::AbstractBlockSparseArrayStyle, + style2::AbstractBlockSparseArrayStyle ) style = Base.Broadcast.result_style(blockstyle(style1), blockstyle(style2)) return BlockSparseArrayStyle(style) end -Base.Broadcast.BroadcastStyle(a::BlockSparseArrayStyle, ::Base.Broadcast.DefaultArrayStyle{0}) = a +function Base.Broadcast.BroadcastStyle( + a::BlockSparseArrayStyle, + ::Base.Broadcast.DefaultArrayStyle{0} + ) + return a +end function Base.Broadcast.BroadcastStyle( ::BlockSparseArrayStyle{N}, a::Base.Broadcast.DefaultArrayStyle ) where {N} @@ -63,7 +66,10 @@ end # which is logic that is handled by `fill!`. const copyto!_blocksparse = blocksparse_style(copyto!) const fill!_blocksparse = blocksparse_style(fill!) -function copyto!_blocksparse(dest::AbstractArray, bc::Broadcasted{<:Base.Broadcast.AbstractArrayStyle{0}}) +function copyto!_blocksparse( + dest::AbstractArray, + bc::Broadcasted{<:Base.Broadcast.AbstractArrayStyle{0}} + ) # `[]` is used to unwrap zero-dimensional arrays. bcf = Base.Broadcast.flatten(bc) value = @allowscalar bcf.f(map(arg -> arg[], bcf.args)...) diff --git a/src/blocksparsearrayinterface/getunstoredblock.jl b/src/blocksparsearrayinterface/getunstoredblock.jl index 1a354b3..f5bb332 100644 --- a/src/blocksparsearrayinterface/getunstoredblock.jl +++ b/src/blocksparsearrayinterface/getunstoredblock.jl @@ -2,13 +2,18 @@ using BlockArrays: Block using FunctionImplementations: zero! struct ZeroBlocks{ - N, A <: AbstractArray{<:Any, N}, ParentAxes <: Tuple{Vararg{AbstractUnitRange{<:Integer}, N}}, + N, A <: AbstractArray{<:Any, N}, + ParentAxes <: Tuple{Vararg{AbstractUnitRange{<:Integer}, N}}, } <: AbstractArray{A, N} parentaxes::ParentAxes end function ZeroBlocks{N, A}( ax::Ax - ) where {N, A <: AbstractArray{<:Any, N}, Ax <: Tuple{Vararg{AbstractUnitRange{<:Integer}, N}}} + ) where { + N, + A <: AbstractArray{<:Any, N}, + Ax <: Tuple{Vararg{AbstractUnitRange{<:Integer}, N}}, + } return ZeroBlocks{N, A, Ax}(ax) end Base.size(a::ZeroBlocks) = map(blocklength, a.parentaxes) @@ -33,7 +38,10 @@ end # TODO: this is a hack and is also type-unstable using LinearAlgebra: Diagonal using TypeParameterAccessors: similartype -function Base.getindex(a::ZeroBlocks{2, A}, I::Vararg{Int, 2}) where {V, A <: Diagonal{<:Any, V}} +function Base.getindex( + a::ZeroBlocks{2, A}, + I::Vararg{Int, 2} + ) where {V, A <: Diagonal{<:Any, V}} ax = ntuple(2) do d return only(axes(a.parentaxes[d][Block(I[d])])) end diff --git a/src/blocksparsearrayinterface/linearalgebra.jl b/src/blocksparsearrayinterface/linearalgebra.jl index e5f4313..e28fe62 100644 --- a/src/blocksparsearrayinterface/linearalgebra.jl +++ b/src/blocksparsearrayinterface/linearalgebra.jl @@ -6,7 +6,7 @@ function mul!_blocksparse( a1::AbstractMatrix, a2::AbstractMatrix, α::Number = true, - β::Number = false, + β::Number = false ) mul!(blocks(a_dest), blocks(a1), blocks(a2), α, β) return a_dest diff --git a/src/blocksparsearrayinterface/map.jl b/src/blocksparsearrayinterface/map.jl index 40259fc..943246f 100644 --- a/src/blocksparsearrayinterface/map.jl +++ b/src/blocksparsearrayinterface/map.jl @@ -9,7 +9,7 @@ function same_block_structure(as::AbstractArray...) ntuple(ndims(first(as))) do dim ax = map(Base.Fix2(axes, dim), as) return blockisequal(ax...) - end, + end ) end @@ -98,12 +98,14 @@ function map!_blocksparse( return blocks_maybe_single(a_srcs[i])[Int.(Tuple(_block(BI_srcs[i])))...] end subblock_dest = @view block_dest[BI_dest.indices...] - subblock_srcs = ntuple(i -> @view(block_srcs[i][BI_srcs[i].indices...]), length(a_srcs)) + subblock_srcs = + ntuple(i -> @view(block_srcs[i][BI_srcs[i].indices...]), length(a_srcs)) I_dest = CartesianIndex(Int.(Tuple(_block(BI_dest)))) # If the function preserves zero values and all of the source blocks are zero, # the output block will be zero. In that case, if the block isn't stored yet, # don't do anything. - if f_preserves_zeros && all(iszero, subblock_srcs) && !isstored(blocks(a_dest), I_dest) + if f_preserves_zeros && all(iszero, subblock_srcs) && + !isstored(blocks(a_dest), I_dest) continue end # TODO: Use `map!!` to handle immutable blocks. @@ -173,7 +175,11 @@ function map_stored_blocks(f, a::AbstractArray) blocktype_a′ = Base.promote_op(f, blocktype(a)) eltype_a′′ = !isconcretetype(eltype_a′) ? Any : eltype_a′ blocktype_a′′ = - !isconcretetype(blocktype_a′) ? AbstractArray{eltype_a′′, ndims(a)} : blocktype_a′ + if !isconcretetype(blocktype_a′) + AbstractArray{eltype_a′′, ndims(a)} + else + blocktype_a′ + end return BlockSparseArray{eltype_a′′, ndims(a), blocktype_a′′}(undef, axes(a)) end stored_blocks = map(B -> f(@view!(a[B])), block_stored_indices) diff --git a/src/factorizations/eig.jl b/src/factorizations/eig.jl index 1f51ced..4a7cf35 100644 --- a/src/factorizations/eig.jl +++ b/src/factorizations/eig.jl @@ -1,9 +1,8 @@ using BlockArrays: blocksizes using DiagonalArrays: diagonal using LinearAlgebra: LinearAlgebra, Diagonal -using MatrixAlgebraKit: MatrixAlgebraKit, diagview -using MatrixAlgebraKit: default_eig_algorithm, eig_full!, eig_vals! -using MatrixAlgebraKit: default_eigh_algorithm, eigh_full!, eigh_vals! +using MatrixAlgebraKit: MatrixAlgebraKit, default_eig_algorithm, default_eigh_algorithm, + diagview, eig_full!, eig_vals!, eigh_full!, eigh_vals! for f in [:default_eig_algorithm, :default_eigh_algorithm] @eval begin diff --git a/src/factorizations/lq.jl b/src/factorizations/lq.jl index 8ae937f..a11c9da 100644 --- a/src/factorizations/lq.jl +++ b/src/factorizations/lq.jl @@ -51,7 +51,8 @@ function MatrixAlgebraKit.initialize_output( end function MatrixAlgebraKit.check_input( - ::typeof(lq_compact!), A::AbstractBlockSparseMatrix, LQ, ::BlockPermutedDiagonalAlgorithm + ::typeof(lq_compact!), A::AbstractBlockSparseMatrix, LQ, + ::BlockPermutedDiagonalAlgorithm ) @assert isblockpermuteddiagonal(A) return nothing diff --git a/src/factorizations/orthnull.jl b/src/factorizations/orthnull.jl index c023f8f..8516257 100644 --- a/src/factorizations/orthnull.jl +++ b/src/factorizations/orthnull.jl @@ -1,13 +1,12 @@ -using MatrixAlgebraKit: MatrixAlgebraKit, AbstractAlgorithm, default_svd_algorithm, - left_null!, left_orth!, left_polar!, lq_compact!, null_truncation_strategy, qr_compact!, - right_null!, right_orth!, right_polar!, select_algorithm, svd_compact! - -using MatrixAlgebraKit: LeftOrthAlgorithm +using MatrixAlgebraKit: MatrixAlgebraKit, AbstractAlgorithm, LeftOrthAlgorithm, + default_svd_algorithm, left_null!, left_orth!, left_polar!, lq_compact!, + null_truncation_strategy, qr_compact!, right_null!, right_orth!, right_polar!, + select_algorithm, svd_compact! for kind in ("polar", "qr", "svd") @eval begin function MatrixAlgebraKit.initialize_output( ::typeof(left_orth!), A::AbstractBlockSparseMatrix, - alg::LeftOrthAlgorithm{Symbol($kind)}, + alg::LeftOrthAlgorithm{Symbol($kind)} ) return nothing end @@ -19,7 +18,7 @@ function MatrixAlgebraKit.check_input( !isnothing(F) && throw( ArgumentError( "`left_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) return nothing end @@ -29,7 +28,7 @@ function MatrixAlgebraKit.left_orth!(A::AbstractBlockSparseMatrix, F, alg::LeftO !isnothing(F) && throw( ArgumentError( "`left_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) alg′ = select_algorithm(qr_compact!, A, alg.alg) return qr_compact!(A, alg′) @@ -39,7 +38,7 @@ function MatrixAlgebraKit.left_orth!(A::AbstractBlockSparseMatrix, F, alg::LeftO !isnothing(F) && throw( ArgumentError( "`left_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) alg′ = select_algorithm(left_polar!, A, alg.alg) return left_polar!(A, alg′) @@ -51,7 +50,7 @@ function MatrixAlgebraKit.left_orth!( !isnothing(F) && throw( ArgumentError( "`left_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) U, S, Vᴴ = if !does_truncate(alg.alg) alg′ = select_algorithm(svd_compact!, A, alg.alg) @@ -69,7 +68,7 @@ for kind in ("lq", "polar", "svd") @eval begin function MatrixAlgebraKit.initialize_output( ::typeof(right_orth!), A::AbstractBlockSparseMatrix, - alg::RightOrthAlgorithm{Symbol($kind)}, + alg::RightOrthAlgorithm{Symbol($kind)} ) return nothing end @@ -77,12 +76,12 @@ for kind in ("lq", "polar", "svd") end function MatrixAlgebraKit.check_input( ::typeof(right_orth!), A::AbstractBlockSparseMatrix, F::Nothing, - alg::AbstractAlgorithm, + alg::AbstractAlgorithm ) !isnothing(F) && throw( ArgumentError( "`right_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) return nothing end @@ -92,7 +91,7 @@ function MatrixAlgebraKit.right_orth!(A::AbstractBlockSparseMatrix, F, alg::Righ !isnothing(F) && throw( ArgumentError( "`right_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) alg′ = select_algorithm(lq_compact!, A, alg.alg) return lq_compact!(A, alg′) @@ -104,7 +103,7 @@ function MatrixAlgebraKit.right_orth!( !isnothing(F) && throw( ArgumentError( "`right_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) alg′ = select_algorithm(right_polar!, A, alg.alg) return right_polar!(A, alg′) @@ -116,7 +115,7 @@ function MatrixAlgebraKit.right_orth!( !isnothing(F) && throw( ArgumentError( "`right_orth!` on block sparse matrices does not support specifying the output" - ), + ) ) U, S, Vᴴ = if !does_truncate(alg.alg) alg′ = select_algorithm(svd_compact!, A, alg.alg) @@ -136,7 +135,7 @@ function MatrixAlgebraKit.initialize_output( end function MatrixAlgebraKit.check_input( ::typeof(left_null!), A::AbstractBlockSparseMatrix, N::Nothing, - alg::AbstractAlgorithm, + alg::AbstractAlgorithm ) return nothing end @@ -148,7 +147,7 @@ end function MatrixAlgebraKit.truncate( ::typeof(left_null!), (U, S)::Tuple{AbstractBlockSparseMatrix, AbstractBlockSparseMatrix}, - strategy::TruncationStrategy, + strategy::TruncationStrategy ) return error("Not implemented.") end @@ -160,7 +159,7 @@ function MatrixAlgebraKit.initialize_output( end function MatrixAlgebraKit.check_input( ::typeof(right_null!), A::AbstractBlockSparseMatrix, N::Nothing, - alg::AbstractAlgorithm, + alg::AbstractAlgorithm ) return nothing end @@ -172,7 +171,7 @@ end function MatrixAlgebraKit.truncate( ::typeof(right_null!), (S, Vᴴ)::Tuple{AbstractBlockSparseMatrix, AbstractBlockSparseMatrix}, - strategy::TruncationStrategy, + strategy::TruncationStrategy ) return error("Not implemented.") end diff --git a/src/factorizations/polar.jl b/src/factorizations/polar.jl index 2dd607e..2b2753c 100644 --- a/src/factorizations/polar.jl +++ b/src/factorizations/polar.jl @@ -1,17 +1,15 @@ -using MatrixAlgebraKit: - MatrixAlgebraKit, - PolarViaSVD, - check_input, - default_algorithm, - left_polar!, - right_polar!, - svd_compact! +using MatrixAlgebraKit: MatrixAlgebraKit, PolarViaSVD, check_input, default_algorithm, + left_polar!, right_polar!, svd_compact! function MatrixAlgebraKit.check_input(::typeof(left_polar!), A::AbstractBlockSparseMatrix) @views for I in eachblockstoredindex(A) m, n = size(A[I]) m >= n || - throw(ArgumentError("each input matrix block needs at least as many rows as columns")) + throw( + ArgumentError( + "each input matrix block needs at least as many rows as columns" + ) + ) end return nothing end @@ -19,7 +17,11 @@ function MatrixAlgebraKit.check_input(::typeof(right_polar!), A::AbstractBlockSp @views for I in eachblockstoredindex(A) m, n = size(A[I]) m <= n || - throw(ArgumentError("each input matrix block needs at least as many columns as rows")) + throw( + ArgumentError( + "each input matrix block needs at least as many columns as rows" + ) + ) end return nothing end diff --git a/src/factorizations/qr.jl b/src/factorizations/qr.jl index 474c345..f4b8b65 100644 --- a/src/factorizations/qr.jl +++ b/src/factorizations/qr.jl @@ -51,7 +51,8 @@ function MatrixAlgebraKit.initialize_output( end function MatrixAlgebraKit.check_input( - ::typeof(qr_compact!), A::AbstractBlockSparseMatrix, QR, ::BlockPermutedDiagonalAlgorithm + ::typeof(qr_compact!), A::AbstractBlockSparseMatrix, QR, + ::BlockPermutedDiagonalAlgorithm ) @assert isblockpermuteddiagonal(A) return nothing diff --git a/src/factorizations/svd.jl b/src/factorizations/svd.jl index 373276e..526b2bb 100644 --- a/src/factorizations/svd.jl +++ b/src/factorizations/svd.jl @@ -1,6 +1,6 @@ using DiagonalArrays: diagonaltype -using MatrixAlgebraKit: MatrixAlgebraKit, check_input, default_svd_algorithm, svd_compact!, - svd_full!, svd_vals! +using MatrixAlgebraKit: + MatrixAlgebraKit, check_input, default_svd_algorithm, svd_compact!, svd_full!, svd_vals! using TypeParameterAccessors: realtype function MatrixAlgebraKit.default_svd_algorithm( @@ -87,12 +87,13 @@ function MatrixAlgebraKit.check_input( ::typeof(svd_compact!), A::AbstractBlockSparseMatrix, USVᴴ, - ::BlockPermutedDiagonalAlgorithm, + ::BlockPermutedDiagonalAlgorithm ) return @assert isblockpermuteddiagonal(A) end function MatrixAlgebraKit.check_input( - ::typeof(svd_compact!), A::AbstractBlockSparseMatrix, (U, S, Vᴴ), ::BlockDiagonalAlgorithm + ::typeof(svd_compact!), A::AbstractBlockSparseMatrix, (U, S, Vᴴ), + ::BlockDiagonalAlgorithm ) @assert isa(U, AbstractBlockSparseMatrix) && isa(S, AbstractBlockSparseMatrix) && @@ -106,7 +107,8 @@ function MatrixAlgebraKit.check_input( end function MatrixAlgebraKit.check_input( - ::typeof(svd_full!), A::AbstractBlockSparseMatrix, USVᴴ, ::BlockPermutedDiagonalAlgorithm + ::typeof(svd_full!), A::AbstractBlockSparseMatrix, USVᴴ, + ::BlockPermutedDiagonalAlgorithm ) @assert isblockpermuteddiagonal(A) return nothing diff --git a/src/factorizations/truncation.jl b/src/factorizations/truncation.jl index 0e8a265..c24ba82 100644 --- a/src/factorizations/truncation.jl +++ b/src/factorizations/truncation.jl @@ -1,13 +1,5 @@ -using MatrixAlgebraKit: - MatrixAlgebraKit, - TruncatedAlgorithm, - TruncationStrategy, - diagview, - eig_trunc!, - eigh_trunc!, - findtruncated, - svd_trunc!, - truncate +using MatrixAlgebraKit: MatrixAlgebraKit, TruncatedAlgorithm, TruncationStrategy, diagview, + eig_trunc!, eigh_trunc!, findtruncated, svd_trunc!, truncate """ BlockDiagonalTruncationStrategy(strategy::TruncationStrategy) @@ -26,7 +18,7 @@ end function MatrixAlgebraKit.svd_trunc!( A::AbstractBlockSparseMatrix, out, - alg::TruncatedAlgorithm{<:BlockPermutedDiagonalAlgorithm}, + alg::TruncatedAlgorithm{<:BlockPermutedDiagonalAlgorithm} ) Ad, (invrowperm, invcolperm) = blockdiagonalize(A) blockalg = BlockDiagonalAlgorithm(alg.alg) @@ -44,7 +36,7 @@ for f in [:eig_trunc!, :eigh_trunc!] function MatrixAlgebraKit.truncate( ::typeof($f), (D, V)::NTuple{2, AbstractBlockSparseMatrix}, - strategy::TruncationStrategy, + strategy::TruncationStrategy ) return truncate($f, (D, V), BlockDiagonalTruncationStrategy(strategy)) end @@ -77,7 +69,7 @@ end function MatrixAlgebraKit.truncate( ::typeof(svd_trunc!), (U, S, Vᴴ)::NTuple{3, AbstractBlockSparseMatrix}, - strategy::BlockDiagonalTruncationStrategy, + strategy::BlockDiagonalTruncationStrategy ) I = findtruncated(diag(S), strategy) return (U[:, I], S[I, I], Vᴴ[I, :]), I @@ -87,7 +79,7 @@ for f in [:eig_trunc!, :eigh_trunc!] function MatrixAlgebraKit.truncate( ::typeof($f), (D, V)::NTuple{2, AbstractBlockSparseMatrix}, - strategy::BlockDiagonalTruncationStrategy, + strategy::BlockDiagonalTruncationStrategy ) I = findtruncated(diag(D), strategy) return (D[I, I], V[:, I]), I diff --git a/test/runtests.jl b/test/runtests.jl index 0008050..16689fa 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,14 +10,19 @@ const GROUP = uppercase( get(ENV, "GROUP", "ALL") else only(match(pat, ARGS[arg_id]).captures) - end, + end ) -"match files of the form `test_*.jl`, but exclude `*setup*.jl`" +""" +match files of the form `test_*.jl`, but exclude `*setup*.jl` +""" function istestfile(fn) - return endswith(fn, ".jl") && startswith(basename(fn), "test_") && !contains(fn, "setup") + return endswith(fn, ".jl") && startswith(basename(fn), "test_") && + !contains(fn, "setup") end -"match files of the form `*.jl`, but exclude `*_notest.jl` and `*setup*.jl`" +""" +match files of the form `*.jl`, but exclude `*_notest.jl` and `*setup*.jl` +""" function isexamplefile(fn) return endswith(fn, ".jl") && !endswith(fn, "_notest.jl") && !contains(fn, "setup") end @@ -57,7 +62,7 @@ end :macrocall, GlobalRef(Suppressor, Symbol("@suppress")), LineNumberNode(@__LINE__, @__FILE__), - :(include($filename)), + :(include($filename)) ) ) end diff --git a/test/test_aqua.jl b/test/test_aqua.jl index cede456..2338854 100644 --- a/test/test_aqua.jl +++ b/test/test_aqua.jl @@ -1,5 +1,5 @@ -using BlockSparseArrays: BlockSparseArrays using Aqua: Aqua +using BlockSparseArrays: BlockSparseArrays using Test: @testset @testset "Code quality (Aqua.jl)" begin diff --git a/test/test_basics.jl b/test/test_basics.jl index 2310ec5..4a78d8d 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -1,46 +1,17 @@ using Adapt: adapt -using BlockArrays: - BlockArrays, - Block, - BlockArray, - BlockRange, - BlockVector, - BlockedOneTo, - BlockedArray, - BlockedVector, - blockedrange, - blocklength, - blocklengths, - blocksize, - blocksizes, - mortar, - undef_blocks -using BlockSparseArrays: - @view!, - BlockSparseArray, - BlockSparseMatrix, - BlockSparseVector, - BlockType, - BlockView, - blockdiagindices, - blockreshape, - blocksparse, - blocksparsezeros, - blockstoredlength, - blockstype, - blocktype, - eachblockstoredindex, - eachstoredblock, - eachstoredblockdiagindex, - similartype_unchecked, - sparsemortar, - view! +using BlockArrays: BlockArrays, Block, BlockArray, BlockRange, BlockVector, BlockedArray, + BlockedOneTo, BlockedVector, blockedrange, blocklength, blocklengths, blocksize, + blocksizes, mortar, undef_blocks +using BlockSparseArrays: @view!, BlockSparseArray, BlockSparseMatrix, BlockSparseVector, + BlockType, BlockView, blockdiagindices, blockreshape, blocksparse, blocksparsezeros, + blockstoredlength, blockstype, blocktype, eachblockstoredindex, eachstoredblock, + eachstoredblockdiagindex, similartype_unchecked, sparsemortar, view! using GPUArraysCore: @allowscalar using JLArrays: JLArray, JLMatrix using LinearAlgebra: Adjoint, Transpose, dot, norm, tr using SparseArraysBase: SparseArrayDOK, SparseMatrixDOK, SparseVectorDOK, isstored, storedlength -using Test: @test, @test_broken, @test_throws, @testset, @inferred +using Test: @inferred, @test, @test_broken, @test_throws, @testset using TestExtras: @constinferred using TypeParameterAccessors: TypeParameterAccessors, Position include("TestBlockSparseArraysUtils.jl") diff --git a/test/test_factorizations.jl b/test/test_factorizations.jl index c29ce48..7189083 100644 --- a/test/test_factorizations.jl +++ b/test/test_factorizations.jl @@ -1,34 +1,11 @@ using Adapt: adapt using BlockArrays: Block, BlockedMatrix, BlockedVector, blocks, mortar -using BlockSparseArrays: - BlockSparseArrays, - BlockDiagonal, - BlockSparseArray, - BlockSparseMatrix, - blockstoredlength, - eachblockstoredindex +using BlockSparseArrays: BlockSparseArrays, BlockDiagonal, BlockSparseArray, + BlockSparseMatrix, blockstoredlength, eachblockstoredindex using LinearAlgebra: LinearAlgebra, Diagonal, hermitianpart, pinv -using MatrixAlgebraKit: - diagview, - eig_full, - eig_trunc, - eig_vals, - eigh_full, - eigh_trunc, - eigh_vals, - left_orth, - left_polar, - lq_compact, - lq_full, - qr_compact, - qr_full, - right_orth, - right_polar, - svd_compact, - svd_full, - svd_trunc, - truncrank, - trunctol +using MatrixAlgebraKit: diagview, eig_full, eig_trunc, eig_vals, eigh_full, eigh_trunc, + eigh_vals, left_orth, left_polar, lq_compact, lq_full, qr_compact, qr_full, right_orth, + right_polar, svd_compact, svd_full, svd_trunc, truncrank, trunctol using Random: Random using StableRNGs: StableRNG using Test: @inferred, @test, @test_throws, @testset @@ -86,7 +63,8 @@ using Test: @inferred, @test, @test_throws, @testset MATRIX_FUNCTIONS = BlockSparseArrays.MATRIX_FUNCTIONS # These functions involve inverses so they break when there are zeros on the diagonal. MATRIX_FUNCTIONS_SINGULAR = [ - :log, :acsc, :asec, :acosh, :acot, :acsch, :asech, :acoth, :csc, :cot, :csch, + :log, :acsc, :asec, :acosh, :acot, :acsch, :asech, :acoth, :csc, :cot, + :csch, :coth, ] MATRIX_FUNCTIONS = setdiff(MATRIX_FUNCTIONS, MATRIX_FUNCTIONS_SINGULAR) @@ -123,7 +101,8 @@ function test_svd(a, (U, S, Vᴴ); full = false) end blockszs = ( - ([2, 2], [2, 2]), ([2, 2], [2, 3]), ([2, 2, 1], [2, 3]), ([2, 3], [2]), ([2], [2, 3]), + ([2, 2], [2, 2]), ([2, 2], [2, 3]), ([2, 2, 1], [2, 3]), ([2, 3], [2]), + ([2], [2, 3]), ) eltypes = (Float32, Float64, ComplexF64) test_params = Iterators.product(blockszs, eltypes) diff --git a/test/test_genericblockindex.jl b/test/test_genericblockindex.jl index 4308d09..60c5c7f 100644 --- a/test/test_genericblockindex.jl +++ b/test/test_genericblockindex.jl @@ -1,23 +1,8 @@ -using BlockArrays: - Block, - BlockIndex, - BlockSlice, - BlockedArray, - BlockedVector, - block, - blockedrange, - blockindex, - mortar -using BlockSparseArrays: - BlockSparseArrays, - BlockIndexVector, - BlockIndices, - GenericBlockIndex, - blocksparsezeros, - blockedunitrange_getindices, - to_block, - to_block_indices, - to_blockindexrange +using BlockArrays: Block, BlockIndex, BlockSlice, BlockedArray, BlockedVector, block, + blockedrange, blockindex, mortar +using BlockSparseArrays: BlockSparseArrays, BlockIndexVector, BlockIndices, + GenericBlockIndex, blockedunitrange_getindices, blocksparsezeros, to_block, + to_block_indices, to_blockindexrange using Test: @test, @test_broken, @testset # blockrange @@ -116,7 +101,10 @@ using Test: @test, @test_broken, @testset @test v[i] == ["d", "c"] v = BlockedVector(["a", "b", "c", "d"], [2, 2]) - i = BlockIndexVector{1, GenericBlockIndex{1, Tuple{Int}, Tuple{String}}}(Block(1), [2, 1]) + i = BlockIndexVector{1, GenericBlockIndex{1, Tuple{Int}, Tuple{String}}}( + Block(1), + [2, 1] + ) @test v[i] == ["b", "a"] i = BlockIndexVector(Block(2), [2, 1]) @test v[i] == ["d", "c"] @@ -132,8 +120,14 @@ using Test: @test, @test_broken, @testset @test a[i2, i2] == [("c", "c") ("c", "d"); ("d", "c") ("d", "d")] a = collect(Iterators.product(v, v)) - i1 = BlockIndexVector{1, GenericBlockIndex{1, Tuple{Int}, Tuple{String}}}(Block(1), [2, 1]) - i2 = BlockIndexVector{1, GenericBlockIndex{1, Tuple{Int}, Tuple{String}}}(Block(2), [1, 2]) + i1 = BlockIndexVector{1, GenericBlockIndex{1, Tuple{Int}, Tuple{String}}}( + Block(1), + [2, 1] + ) + i2 = BlockIndexVector{1, GenericBlockIndex{1, Tuple{Int}, Tuple{String}}}( + Block(2), + [1, 2] + ) i = BlockIndexVector{2, GenericBlockIndex{2, Tuple{Int, Int}, Tuple{String, String}}}( Block(1, 2), ([2, 1], [1, 2]) ) diff --git a/test/test_issues.jl b/test/test_issues.jl index cb84948..f660f50 100644 --- a/test/test_issues.jl +++ b/test/test_issues.jl @@ -1,8 +1,8 @@ using BlockArrays using BlockSparseArrays using BlockSparseArrays: blocksparse -using MatrixAlgebraKit using LinearAlgebra: LinearAlgebra +using MatrixAlgebraKit using Test: @test, @testset @testset "Issue 162" begin diff --git a/test/test_map.jl b/test/test_map.jl index 6497eeb..fcd9f36 100644 --- a/test/test_map.jl +++ b/test/test_map.jl @@ -1,15 +1,7 @@ using Adapt: adapt using BlockArrays: Block, BlockRange, blockedrange, blocksize, blocksizes, mortar -using BlockSparseArrays: - BlockSparseArray, - BlockSparseVector, - BlockVector, - BlockView, - BlockedVector, - blocklengths, - blockstoredlength, - blocktype, - eachblockstoredindex +using BlockSparseArrays: BlockSparseArray, BlockSparseVector, BlockVector, BlockView, + BlockedVector, blocklengths, blockstoredlength, blocktype, eachblockstoredindex using FunctionImplementations: zero! using GPUArraysCore: @allowscalar using JLArrays: JLArray diff --git a/test/test_similartype_unchecked.jl b/test/test_similartype_unchecked.jl index cdb1799..d7fac73 100644 --- a/test/test_similartype_unchecked.jl +++ b/test/test_similartype_unchecked.jl @@ -6,16 +6,21 @@ using TestExtras: @constinferred @testset "similartype_unchecked" begin @test @constinferred(similartype_unchecked(Array{Float32}, NTuple{2, Int})) === Matrix{Float32} - @test @constinferred(similartype_unchecked(Array{Float32}, NTuple{2, Base.OneTo{Int}})) === + @test @constinferred( + similartype_unchecked(Array{Float32}, NTuple{2, Base.OneTo{Int}}) + ) === Matrix{Float32} if VERSION < v"1.11-" # Not type stable in Julia 1.10. - @test similartype_unchecked(AbstractArray{Float32}, NTuple{2, Int}) === Matrix{Float32} + @test similartype_unchecked(AbstractArray{Float32}, NTuple{2, Int}) === + Matrix{Float32} @test similartype_unchecked(JLArray{Float32}, NTuple{2, Int}) === JLMatrix{Float32} @test similartype_unchecked(JLArray{Float32}, NTuple{2, Base.OneTo{Int}}) === JLMatrix{Float32} else - @test @constinferred(similartype_unchecked(AbstractArray{Float32}, NTuple{2, Int})) === + @test @constinferred( + similartype_unchecked(AbstractArray{Float32}, NTuple{2, Int}) + ) === Matrix{Float32} @test @constinferred(similartype_unchecked(JLArray{Float32}, NTuple{2, Int})) === JLMatrix{Float32} diff --git a/test/test_tensoralgebraext.jl b/test/test_tensoralgebraext.jl index 11cef60..cb15aa8 100644 --- a/test/test_tensoralgebraext.jl +++ b/test/test_tensoralgebraext.jl @@ -22,7 +22,12 @@ end end @testset "`contract` `BlockSparseArray` (eltype=$elt)" for elt in - (Float32, Float64, Complex{Float32}, Complex{Float64}) + ( + Float32, + Float64, + Complex{Float32}, + Complex{Float64}, + ) @testset "BlockedOneTo" begin d = blockedrange([2, 3]) a1 = randn_blockdiagonal(elt, (d, d, d, d)) @@ -44,7 +49,8 @@ end # matrix vector a_dest, dimnames_dest = contract(a1, (2, -1, -2, 1), a3, (1, 2)) - a_dest_dense, dimnames_dest_dense = contract(a1_dense, (2, -1, -2, 1), a3_dense, (1, 2)) + a_dest_dense, dimnames_dest_dense = + contract(a1_dense, (2, -1, -2, 1), a3_dense, (1, 2)) @test dimnames_dest == dimnames_dest_dense @test size(a_dest) == size(a_dest_dense) @test a_dest isa BlockSparseArray @@ -52,7 +58,8 @@ end # vector matrix a_dest, dimnames_dest = contract(a3, (1, 2), a1, (2, -1, -2, 1)) - a_dest_dense, dimnames_dest_dense = contract(a3_dense, (1, 2), a1_dense, (2, -1, -2, 1)) + a_dest_dense, dimnames_dest_dense = + contract(a3_dense, (1, 2), a1_dense, (2, -1, -2, 1)) @test dimnames_dest == dimnames_dest_dense @test size(a_dest) == size(a_dest_dense) @test a_dest isa BlockSparseArray diff --git a/test/test_view_bang.jl b/test/test_view_bang.jl index 329fd23..ccb6250 100644 --- a/test/test_view_bang.jl +++ b/test/test_view_bang.jl @@ -1,7 +1,7 @@ using Adapt: adapt using BlockArrays: Block using BlockSparseArrays: - BlockSparseArray, @view!, blockstoredlength, eachblockstoredindex, view! + @view!, BlockSparseArray, blockstoredlength, eachblockstoredindex, view! using JLArrays: JLArray using SparseArraysBase: isstored using Test: @test, @testset