From 00bc73a0501821d183148b9d7285d1606e20bdf9 Mon Sep 17 00:00:00 2001 From: Matt Fishman Date: Tue, 26 Nov 2024 18:30:42 -0500 Subject: [PATCH] Package setup (#2) --- .JuliaFormatter.toml | 1 + .github/ISSUE_TEMPLATE/BUG_REPORT.md | 62 +++++++++ .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md | 24 ++++ .github/PULL_REQUEST_TEMPLATE.md | 42 ++++++ .github/dependabot.yml | 7 + .github/workflows/CI.yml | 79 +++++++++++ .github/workflows/CompatHelper.yml | 16 +++ .github/workflows/FormatCheck.yml | 35 +++++ .github/workflows/LiterateCheck.yml | 43 ++++++ .github/workflows/Register.yml | 16 +++ .github/workflows/TagBot.yml | 31 +++++ .gitignore | 14 ++ .pre-commit-config.yaml | 13 ++ LICENSE | 21 +++ Project.toml | 44 +++++++ README.md | 124 +++--------------- TODO.md | 124 ++++++++++++++++++ benchmark/benchmarks.jl | 7 + docs/Project.toml | 12 ++ docs/make.jl | 24 ++++ docs/make_index.jl | 9 ++ docs/make_readme.jl | 9 ++ examples/Project.toml | 10 ++ examples/README.jl | 23 ++++ src/SparseArraysBase.jl | 2 + .../SparseArraysBaseSparseArraysExt.jl | 2 +- src/abstractsparsearray/arraylayouts.jl | 2 +- src/sparsearrayinterface/broadcast.jl | 2 +- src/sparsearrayinterface/densearray.jl | 2 +- src/sparsearrayinterface/wrappers.jl | 2 +- test/Project.toml | 6 +- .../AbstractSparseArrays.jl | 2 +- .../DiagonalArrays.jl | 2 +- test/SparseArraysBaseTestUtils/Project.toml | 2 - .../SparseArraysBaseTestUtils/SparseArrays.jl | 12 +- test/runtests.jl | 11 +- test/test_abstractsparsearray.jl | 4 +- test/test_array.jl | 2 +- test/test_diagonalarray.jl | 2 +- test/test_sparsearraydok.jl | 5 +- 40 files changed, 718 insertions(+), 132 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/BUG_REPORT.md create mode 100644 .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/CI.yml create mode 100644 .github/workflows/CompatHelper.yml create mode 100644 .github/workflows/FormatCheck.yml create mode 100644 .github/workflows/LiterateCheck.yml create mode 100644 .github/workflows/Register.yml create mode 100644 .github/workflows/TagBot.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 LICENSE create mode 100644 Project.toml create mode 100644 TODO.md create mode 100644 benchmark/benchmarks.jl create mode 100644 docs/Project.toml create mode 100644 docs/make.jl create mode 100644 docs/make_index.jl create mode 100644 docs/make_readme.jl create mode 100644 examples/Project.toml create mode 100644 examples/README.jl delete mode 100644 test/SparseArraysBaseTestUtils/Project.toml diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml index 08f664c..4c49a86 100644 --- a/.JuliaFormatter.toml +++ b/.JuliaFormatter.toml @@ -1,2 +1,3 @@ +# See https://domluna.github.io/JuliaFormatter.jl/stable/ for a list of options style = "blue" indent = 2 diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md new file mode 100644 index 0000000..1132644 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -0,0 +1,62 @@ +--- +name: SparseArraysBase.jl bug report +about: Create a bug report to help us improve SparseArraysBase.jl +title: "[BUG] YOUR SHORT DESCRIPTION OF THE BUG HERE" +labels: ["bug"] +assignees: '' + +--- + +**Description of bug** + +Please give a brief description of the bug or unexpected behavior here. + +**Minimal code demonstrating the bug or unexpected behavior** + +If applicable, provide a minimal code that can be run to demonstrate the bug or unexpected behavior. + +If you are unable to construct a minimal code that demonstrates the bug or unexpected behavior, provide detailed steps for how to reproduce the behavior you are seeing. + +
Minimal runnable code

+ +```julia +[YOUR MINIMAL RUNNABLE CODE HERE] +``` + +

+ + +**Expected output or behavior** + +Describe what you expected to happen. + +If you provided a minimal code that can be run to demonstrate the bug or unexpected behavior, describe what you expected the output would be. + + +**Actual output or behavior** + +Describe what actually happened. + +If you provided a minimal code that demonstrates the bug or unexpected behavior, provide the output you get from that code. If the code leads to an error or warning, include the full error or warning below. + +
Output of minimal runnable code

+ +```julia +[OUTPUT OF YOUR MINIMAL RUNNABLE CODE HERE] +``` + +

+ + +**Version information** + + - Output from `versioninfo()`: +```julia +julia> versioninfo() +[YOUR OUTPUT HERE] +``` + - Output from `using Pkg; Pkg.status("SparseArraysBase")`: +```julia +julia> using Pkg; Pkg.status("SparseArraysBase") +[YOUR OUTPUT HERE] +``` diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md new file mode 100644 index 0000000..25cd58c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -0,0 +1,24 @@ +--- +name: SparseArraysBase.jl feature request +about: Suggest an idea for SparseArraysBase.jl +title: "[ENHANCEMENT] YOUR SHORT DESCRIPTION OF THE FEATURE REQUEST HERE" +labels: ["enhancement"] +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** + +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** + +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** + +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** + +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..7f2c223 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,42 @@ +# Description + +Please include a summary of the change and which issue is fixed (if applicable). Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes #(issue) + +If practical and applicable, please include a minimal demonstration of the previous behavior and new behavior below. + +
Minimal demonstration of previous behavior

+ +```julia +[YOUR MINIMAL DEMONSTRATION OF PREVIOUS BEHAVIOR] +``` + +

+ +
Minimal demonstration of new behavior

+ +```julia +[YOUR MINIMAL DEMONSTRATION OF NEW BEHAVIOR] +``` + +

+ +# How Has This Been Tested? + +Please add tests that verify your changes to a file in the `test` directory. + +Please give a summary of the tests that you added to verify your changes. + +- [ ] Test A +- [ ] Test B + +# Checklist: + +- [ ] My code follows the style guidelines of this project. Please run `using JuliaFormatter; format(".")` in the base directory of the repository (`~/.julia/dev/SparseArraysBase`) to format your code according to our style guidelines. +- [ ] I have performed a self-review of my own code. +- [ ] I have commented my code, particularly in hard-to-understand areas. +- [ ] I have added tests that verify the behavior of the changes I made. +- [ ] I have made corresponding changes to the documentation. +- [ ] My changes generate no new warnings. +- [ ] Any dependent changes have been merged and published in downstream modules. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..700707c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..7b26073 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,79 @@ +name: CI +on: + push: + branches: + - main + tags: ['*'] + pull_request: + workflow_dispatch: +concurrency: + # Skip intermediate builds: always. + # Cancel intermediate builds: only if it is a pull request build. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created + actions: write + contents: read + strategy: + fail-fast: false + matrix: + version: + # - 'lts' # TODO: Reenable once dependencies are registered. + - '1' + os: + - ubuntu-latest + - macOS-latest + - windows-latest + arch: + - x64 + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: julia-actions/cache@v2 + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-processcoverage@v1 + - uses: codecov/codecov-action@v5 + with: + files: lcov.info + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false + docs: + name: Documentation + runs-on: ubuntu-latest + permissions: + actions: write # needed to allow julia-actions/cache to proactively delete old caches that it has created + contents: write + statuses: write + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: '1' + - uses: julia-actions/cache@v2 + - name: Configure doc environment + shell: julia --project=docs --color=yes {0} + run: | + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-docdeploy@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} + - name: Run doctests + shell: julia --project=docs --color=yes {0} + run: | + using Documenter: DocMeta, doctest + using SparseArraysBase + DocMeta.setdocmeta!(SparseArraysBase, :DocTestSetup, :(using SparseArraysBase); recursive=true) + doctest(SparseArraysBase) diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml new file mode 100644 index 0000000..cba9134 --- /dev/null +++ b/.github/workflows/CompatHelper.yml @@ -0,0 +1,16 @@ +name: CompatHelper +on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: +jobs: + CompatHelper: + runs-on: ubuntu-latest + steps: + - name: Pkg.add("CompatHelper") + run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} + run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/.github/workflows/FormatCheck.yml b/.github/workflows/FormatCheck.yml new file mode 100644 index 0000000..bb6d933 --- /dev/null +++ b/.github/workflows/FormatCheck.yml @@ -0,0 +1,35 @@ +name: Format check +on: + push: + branches: [main] + tags: [v*] + pull_request: + +jobs: + format: + name: "Format Check" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: 1 + - name: Install JuliaFormatter and format + run: | + julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter"))' + julia -e 'using JuliaFormatter; format(".", verbose=true)' + - name: Check format + run: | + julia -e ' + out = Cmd(`git diff --name-only`) |> read |> String + if out == "" + exit(0) + else + @error "The following files have not been formatted:" + write(stdout, out) + out_diff = Cmd(`git diff`) |> read |> String + @error "Diff:" + write(stdout, out_diff) + exit(1) + @error "" + end' diff --git a/.github/workflows/LiterateCheck.yml b/.github/workflows/LiterateCheck.yml new file mode 100644 index 0000000..38d9b32 --- /dev/null +++ b/.github/workflows/LiterateCheck.yml @@ -0,0 +1,43 @@ +name: Literate check +on: + push: + branches: [main] + tags: [v*] + pull_request: + +jobs: + literate: + name: "Literate Check" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: 1 + - name: Install Literate and generate docs + run: | + julia -e ' + using Pkg + # TODO: Delete once they are registered. + Pkg.add(url="https://github.com/ITensor/BroadcastMapConversion.jl") + Pkg.add(url="https://github.com/ITensor/NestedPermutedDimsArrays.jl") + Pkg.add(url="https://github.com/ITensor/TypeParameterAccessors.jl") + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + Pkg.add(PackageSpec(name="Literate"))' + julia -e 'include("docs/make_readme.jl")' + - name: Check if docs need to be updated + run: | + julia -e ' + out = Cmd(`git diff --name-only`) |> read |> String + if out == "" + exit(0) + else + @error "The docs are outdated, rerun Literate to regenerate them." + write(stdout, out) + out_diff = Cmd(`git diff`) |> read |> String + @error "Diff:" + write(stdout, out_diff) + exit(1) + @error "" + end' diff --git a/.github/workflows/Register.yml b/.github/workflows/Register.yml new file mode 100644 index 0000000..5b7cd3b --- /dev/null +++ b/.github/workflows/Register.yml @@ -0,0 +1,16 @@ +name: Register Package +on: + workflow_dispatch: + inputs: + version: + description: Version to register or component to bump + required: true +jobs: + register: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: julia-actions/RegisterAction@latest + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 0000000..0cd3114 --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -0,0 +1,31 @@ +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 +jobs: + TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10593a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +*.jl.*.cov +*.jl.cov +*.jl.mem +*.o +*.swp +.DS_Store +.benchmarkci +.tmp +.vscode/ +Manifest.toml +benchmark/*.json +docs/Manifest.toml +docs/build/ +docs/src/index.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..bff1fb7 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.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/qiaojunfeng/pre-commit-julia-format + rev: v0.2.0 + hooks: + - id: julia-format diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7f5c8c6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 ITensor developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..4d5984b --- /dev/null +++ b/Project.toml @@ -0,0 +1,44 @@ +name = "SparseArraysBase" +uuid = "0d5efcca-f356-4864-8770-e1ed8d78f208" +authors = ["ITensor developers and contributors"] +version = "0.1.0" + +[deps] +Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +BroadcastMapConversion = "4a4adec5-520f-4750-bb37-d5e66b4ddeb2" +Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" +Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +NestedPermutedDimsArrays = "2c2a8ec4-3cfc-4276-aa3e-1307b4294e58" +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" +VectorInterface = "409d34a3-91d5-4945-b6ec-7529ddf182d8" + +[sources] +BroadcastMapConversion = {url = "https://github.com/ITensor/BroadcastMapConversion.jl"} +NestedPermutedDimsArrays = {url = "https://github.com/ITensor/NestedPermutedDimsArrays.jl"} +TypeParameterAccessors = {url = "https://github.com/ITensor/TypeParameterAccessors.jl"} + +[compat] +Accessors = "0.1.38" +Adapt = "4.1.1" +Aqua = "0.8.9" +ArrayLayouts = "1.10.4" +Compat = "4.16.0" +Dictionaries = "0.4.3" +LinearAlgebra = "1.10" +MacroTools = "0.5.13" +SparseArrays = "1.10" +Test = "1.10" +VectorInterface = "0.5.0" +julia = "1.10" + +[extras] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Aqua", "Test"] diff --git a/README.md b/README.md index 629cc07..2f2f208 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,29 @@ -# SparseArraysBase +# SparseArraysBase.jl -SparseArraysBase is a package that aims to expand on the sparse array functionality that is currently in Julia Base. -While SparseArrays.jl is centered mostly around `SparseMatrixCSC` and the SuiteSparse library, here we wish to broaden the scope a bit, and consider generic sparse arrays. -Abstractly, the mental model can be considered as a storage object that holds the stored values, and a bijection between the array indices and the indices of the storage. -For now, we focus on providing efficient implementations of Dictionary of Key (DOK) type sparse storage formats, but may expand upon this in the future. -As a result, for typical linear algebra routines, we still expect `SparseMatrixCSC` to be the object of choice. +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://ITensor.github.io/SparseArraysBase.jl/stable/) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://ITensor.github.io/SparseArraysBase.jl/dev/) +[![Build Status](https://github.com/ITensor/SparseArraysBase.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/ITensor/SparseArraysBase.jl/actions/workflows/CI.yml?query=branch%3Amain) +[![Coverage](https://codecov.io/gh/ITensor/SparseArraysBase.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ITensor/SparseArraysBase.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) -The design consists of roughly three components: -- `AbstractSparseArray` interface functions -- Overloaded Julia base methods -- `SparseArrayDOK` struct that implements this - -## AbstractSparseArray - -The first part consists of typical functions that are useful in the context of sparse arrays. -The minimal interface, which enables the usage of the rest of this package, consists of the following functions: - -| Signature | Description | Default | -|-----------|-------------|---------| -| `sparse_storage(a::AbstractArray)` | Returns the storage object of the sparse array | `a` | -| `storage_index_to_index(a::AbstractArray, I)` | Converts a storage index to an array index | `I` | -| `index_to_storage_index(a::AbstractArray, I)` | Converts an array index to a storage index | `I` | - -Using these primitives, several convenience functions are defined to facilitate the writing of sparse array algorithms. - -| Signature | Description | Default | -|-----------|-------------|---------| -| `storage_indices(a)` | Returns the indices of the storage | `eachindex(sparse_storage(a))` | -| `stored_indices(a)` | Returns the indices of the stored values | `Iterators.map(Base.Fix1(storage_index_to_index, a), storage_indices(a))` | -| `stored_length(a)` | Returns the number of stored values | `length(storage_indices(a))` | - - - -Interesting to note here is that the design is such that we can define sparse arrays without having to subtype `AbstractSparseArray`. -To achieve this, each function `f` is defined in terms of `sparse_f`, rather than directly overloading `f`. - - -## Overloaded Julia base methods +julia> using Pkg: Pkg -The second part consists of overloading Julia base methods to work with sparse arrays. -In particular, specialised implementations exist for the following functions: - -- `sparse_similar` -- `sparse_reduce` -- `sparse_map` -- `sparse_map!` -- `sparse_all` -- `sparse_any` -- `sparse_isequal` -- `sparse_fill!` -- `sparse_zero`, `sparse_zero!`, `sparse_iszero` -- `sparse_one`, `sparse_one!`, `sparse_isone` -- `sparse_reshape`, `sparse_reshape!` -- `sparse_cat`, `sparse_cat!` -- `sparse_copy!`, `sparse_copyto!` -- `sparse_permutedims`, `sparse_permutedims!` -- `sparse_mul!`, `sparse_dot` +julia> Pkg.add("https://github.com/ITensor/SparseArraysBase.jl") +``` -## SparseArrayDOK +## Examples -Finally, the `SparseArrayDOK` struct is provided as a concrete implementation of the `AbstractSparseArray` interface. -It is a dictionary of keys (DOK) type sparse array, which stores the values in a `Dictionaries.jl` dictionary, and maps the indices to the keys of the dictionary. -This model is particularly useful for sparse arrays with a small number of non-zero elements, or for arrays that are constructed incrementally, as it boasts fast random accesses and insertions. -The drawback is that sequential iteration is slower than for other sparse array types, leading to slower linear algebra operations. -For the purposes of `SparseArraysBase`, this struct will serve as the canonical example of a sparse array, and will be returned by default when new sparse arrays are created. +````julia +using SparseArraysBase: SparseArraysBase +```` -One particular feature of `SparseArrayDOK` is that it can be used in cases where the non-stored entries have to be constructed in a non-trivial way. -Typically, sparse arrays use `zero(eltype(a))` to construct the non-stored entries, but this is not always sufficient. -A concrete example is found in `BlockSparseArrays.jl`, where initialization of the non-stored entries requires the construction of a block of zeros of appropriate size. +Examples go here. - +--- -## TODO -Still need to implement `Base` functions: -```julia -[x] sparse_zero(a::AbstractArray) = similar(a) -[x] sparse_iszero(a::AbstractArray) = iszero(nonzero_length(a)) # Uses `all`, make `sparse_all`? -[x] sparse_one(a::AbstractArray) = ... -[x] sparse_isreal(a::AbstractArray) = ... # Uses `all`, make `sparse_all`? -[x] sparse_isequal(a1::AbstractArray, a2::AbstractArray) = ... -[x] sparse_conj!(a::AbstractArray) = conj!(nonzeros(a)) -[x] sparse_reshape(a::AbstractArray, dims) = ... -[ ] sparse_all(f, a::AbstractArray) = ... -[ ] sparse_getindex(a::AbstractArray, 1:2, 2:3) = ... # Slicing -``` -`LinearAlgebra` functions: -```julia -[ ] sparse_mul! -[ ] sparse_lmul! -[ ] sparse_ldiv! -[ ] sparse_rdiv! -[ ] sparse_axpby! -[ ] sparse_axpy! -[ ] sparse_norm -[ ] sparse_dot/sparse_inner -[ ] sparse_adoint! -[ ] sparse_transpose! +*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* -# Using conversion to `SparseMatrixCSC`: -[ ] sparse_qr -[ ] sparse_eigen -[ ] sparse_svd -``` -`TensorAlgebra` functions: -```julia -[ ] add! -[ ] contract! -``` diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..300cf62 --- /dev/null +++ b/TODO.md @@ -0,0 +1,124 @@ +# To-do + +- Remove Compat.jl from dependencies and test dependencies. +- Unregistered dependencies: BroadcastMapConversion, NestedPermutedDimsArrays, TypeParameterAccessors. +- Create SparseArraysBaseLinearAlgebraExt, SparseArraysBaseNestedPermutedDimsArraysExt, SparseArraysBaseVectorInterfaceExt. +- Change [sources] entries from paths to urls. + +# SparseArraysBase + +SparseArraysBase is a package that aims to expand on the sparse array functionality that is currently in Julia Base. +While SparseArrays.jl is centered mostly around `SparseMatrixCSC` and the SuiteSparse library, here we wish to broaden the scope a bit, and consider generic sparse arrays. +Abstractly, the mental model can be considered as a storage object that holds the stored values, and a bijection between the array indices and the indices of the storage. +For now, we focus on providing efficient implementations of Dictionary of Key (DOK) type sparse storage formats, but may expand upon this in the future. +As a result, for typical linear algebra routines, we still expect `SparseMatrixCSC` to be the object of choice. + +The design consists of roughly three components: +- `AbstractSparseArray` interface functions +- Overloaded Julia base methods +- `SparseArrayDOK` struct that implements this + +## AbstractSparseArray + +The first part consists of typical functions that are useful in the context of sparse arrays. +The minimal interface, which enables the usage of the rest of this package, consists of the following functions: + +| Signature | Description | Default | +|-----------|-------------|---------| +| `sparse_storage(a::AbstractArray)` | Returns the storage object of the sparse array | `a` | +| `storage_index_to_index(a::AbstractArray, I)` | Converts a storage index to an array index | `I` | +| `index_to_storage_index(a::AbstractArray, I)` | Converts an array index to a storage index | `I` | + +Using these primitives, several convenience functions are defined to facilitate the writing of sparse array algorithms. + +| Signature | Description | Default | +|-----------|-------------|---------| +| `storage_indices(a)` | Returns the indices of the storage | `eachindex(sparse_storage(a))` | +| `stored_indices(a)` | Returns the indices of the stored values | `Iterators.map(Base.Fix1(storage_index_to_index, a), storage_indices(a))` | +| `stored_length(a)` | Returns the number of stored values | `length(storage_indices(a))` | + + + +Interesting to note here is that the design is such that we can define sparse arrays without having to subtype `AbstractSparseArray`. +To achieve this, each function `f` is defined in terms of `sparse_f`, rather than directly overloading `f`. + + +## Overloaded Julia base methods + +The second part consists of overloading Julia base methods to work with sparse arrays. +In particular, specialised implementations exist for the following functions: + +- `sparse_similar` +- `sparse_reduce` +- `sparse_map` +- `sparse_map!` +- `sparse_all` +- `sparse_any` +- `sparse_isequal` +- `sparse_fill!` +- `sparse_zero`, `sparse_zero!`, `sparse_iszero` +- `sparse_one`, `sparse_one!`, `sparse_isone` +- `sparse_reshape`, `sparse_reshape!` +- `sparse_cat`, `sparse_cat!` +- `sparse_copy!`, `sparse_copyto!` +- `sparse_permutedims`, `sparse_permutedims!` +- `sparse_mul!`, `sparse_dot` + +## SparseArrayDOK + +Finally, the `SparseArrayDOK` struct is provided as a concrete implementation of the `AbstractSparseArray` interface. +It is a dictionary of keys (DOK) type sparse array, which stores the values in a `Dictionaries.jl` dictionary, and maps the indices to the keys of the dictionary. +This model is particularly useful for sparse arrays with a small number of non-zero elements, or for arrays that are constructed incrementally, as it boasts fast random accesses and insertions. +The drawback is that sequential iteration is slower than for other sparse array types, leading to slower linear algebra operations. +For the purposes of `SparseArraysBase`, this struct will serve as the canonical example of a sparse array, and will be returned by default when new sparse arrays are created. + +One particular feature of `SparseArrayDOK` is that it can be used in cases where the non-stored entries have to be constructed in a non-trivial way. +Typically, sparse arrays use `zero(eltype(a))` to construct the non-stored entries, but this is not always sufficient. +A concrete example is found in `BlockSparseArrays.jl`, where initialization of the non-stored entries requires the construction of a block of zeros of appropriate size. + + + +## TODO +Still need to implement `Base` functions: +```julia +[x] sparse_zero(a::AbstractArray) = similar(a) +[x] sparse_iszero(a::AbstractArray) = iszero(nonzero_length(a)) # Uses `all`, make `sparse_all`? +[x] sparse_one(a::AbstractArray) = ... +[x] sparse_isreal(a::AbstractArray) = ... # Uses `all`, make `sparse_all`? +[x] sparse_isequal(a1::AbstractArray, a2::AbstractArray) = ... +[x] sparse_conj!(a::AbstractArray) = conj!(nonzeros(a)) +[x] sparse_reshape(a::AbstractArray, dims) = ... +[ ] sparse_all(f, a::AbstractArray) = ... +[ ] sparse_getindex(a::AbstractArray, 1:2, 2:3) = ... # Slicing +``` +`LinearAlgebra` functions: +```julia +[ ] sparse_mul! +[ ] sparse_lmul! +[ ] sparse_ldiv! +[ ] sparse_rdiv! +[ ] sparse_axpby! +[ ] sparse_axpy! +[ ] sparse_norm +[ ] sparse_dot/sparse_inner +[ ] sparse_adoint! +[ ] sparse_transpose! + +# Using conversion to `SparseMatrixCSC`: +[ ] sparse_qr +[ ] sparse_eigen +[ ] sparse_svd +``` +`TensorAlgebra` functions: +```julia +[ ] add! +[ ] contract! +``` diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl new file mode 100644 index 0000000..37e4768 --- /dev/null +++ b/benchmark/benchmarks.jl @@ -0,0 +1,7 @@ +using SparseArraysBase +using BenchmarkTools + +SUITE = BenchmarkGroup() +SUITE["rand"] = @benchmarkable rand(10) + +# Write your benchmarks here. diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..fafc7bc --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,12 @@ +[deps] +BroadcastMapConversion = "4a4adec5-520f-4750-bb37-d5e66b4ddeb2" +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306" +NestedPermutedDimsArrays = "2c2a8ec4-3cfc-4276-aa3e-1307b4294e58" +SparseArraysBase = "0d5efcca-f356-4864-8770-e1ed8d78f208" +TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" + +[sources] +BroadcastMapConversion = {url = "https://github.com/ITensor/BroadcastMapConversion.jl"} +NestedPermutedDimsArrays = {url = "https://github.com/ITensor/NestedPermutedDimsArrays.jl"} +TypeParameterAccessors = {url = "https://github.com/ITensor/TypeParameterAccessors.jl"} diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 0000000..8d4c368 --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,24 @@ +using SparseArraysBase: SparseArraysBase +using Documenter: Documenter, DocMeta, deploydocs, makedocs + +DocMeta.setdocmeta!( + SparseArraysBase, :DocTestSetup, :(using SparseArraysBase); recursive=true +) + +include("make_index.jl") + +makedocs(; + modules=[SparseArraysBase], + authors="ITensor developers and contributors", + sitename="SparseArraysBase.jl", + format=Documenter.HTML(; + canonical="https://ITensor.github.io/SparseArraysBase.jl", + edit_link="main", + assets=String[], + ), + pages=["Home" => "index.md"], +) + +deploydocs(; + repo="github.com/ITensor/SparseArraysBase.jl", devbranch="main", push_preview=true +) diff --git a/docs/make_index.jl b/docs/make_index.jl new file mode 100644 index 0000000..bd8577c --- /dev/null +++ b/docs/make_index.jl @@ -0,0 +1,9 @@ +using Literate: Literate +using SparseArraysBase: SparseArraysBase + +Literate.markdown( + joinpath(pkgdir(SparseArraysBase), "examples", "README.jl"), + joinpath(pkgdir(SparseArraysBase), "docs", "src"); + flavor=Literate.DocumenterFlavor(), + name="index", +) diff --git a/docs/make_readme.jl b/docs/make_readme.jl new file mode 100644 index 0000000..b53bfcf --- /dev/null +++ b/docs/make_readme.jl @@ -0,0 +1,9 @@ +using Literate: Literate +using SparseArraysBase: SparseArraysBase + +Literate.markdown( + joinpath(pkgdir(SparseArraysBase), "examples", "README.jl"), + joinpath(pkgdir(SparseArraysBase)); + flavor=Literate.CommonMarkFlavor(), + name="README", +) diff --git a/examples/Project.toml b/examples/Project.toml new file mode 100644 index 0000000..0c45434 --- /dev/null +++ b/examples/Project.toml @@ -0,0 +1,10 @@ +[deps] +BroadcastMapConversion = "4a4adec5-520f-4750-bb37-d5e66b4ddeb2" +NestedPermutedDimsArrays = "2c2a8ec4-3cfc-4276-aa3e-1307b4294e58" +SparseArraysBase = "0d5efcca-f356-4864-8770-e1ed8d78f208" +TypeParameterAccessors = "7e5a90cf-f82e-492e-a09b-e3e26432c138" + +[sources] +BroadcastMapConversion = {url = "https://github.com/ITensor/BroadcastMapConversion.jl"} +NestedPermutedDimsArrays = {url = "https://github.com/ITensor/NestedPermutedDimsArrays.jl"} +TypeParameterAccessors = {url = "https://github.com/ITensor/TypeParameterAccessors.jl"} diff --git a/examples/README.jl b/examples/README.jl new file mode 100644 index 0000000..dfda702 --- /dev/null +++ b/examples/README.jl @@ -0,0 +1,23 @@ +# # SparseArraysBase.jl +# +# [![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://ITensor.github.io/SparseArraysBase.jl/stable/) +# [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://ITensor.github.io/SparseArraysBase.jl/dev/) +# [![Build Status](https://github.com/ITensor/SparseArraysBase.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/ITensor/SparseArraysBase.jl/actions/workflows/CI.yml?query=branch%3Amain) +# [![Coverage](https://codecov.io/gh/ITensor/SparseArraysBase.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/ITensor/SparseArraysBase.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) + +# ## Installation instructions + +#= +```julia +julia> using Pkg: Pkg + +julia> Pkg.add("https://github.com/ITensor/SparseArraysBase.jl") +``` +=# + +# ## Examples + +using SparseArraysBase: SparseArraysBase +# Examples go here. diff --git a/src/SparseArraysBase.jl b/src/SparseArraysBase.jl index 0a9ff4f..6d264c6 100644 --- a/src/SparseArraysBase.jl +++ b/src/SparseArraysBase.jl @@ -1,4 +1,5 @@ module SparseArraysBase + include("sparsearrayinterface/arraylayouts.jl") include("sparsearrayinterface/densearray.jl") include("sparsearrayinterface/vectorinterface.jl") @@ -33,4 +34,5 @@ include("sparsearraydok/sparsearraydok.jl") include("sparsearraydok/sparsematrixdok.jl") include("sparsearraydok/sparsevectordok.jl") include("sparsearraydok/arraylayouts.jl") + end diff --git a/src/abstractsparsearray/SparseArraysBaseSparseArraysExt.jl b/src/abstractsparsearray/SparseArraysBaseSparseArraysExt.jl index 492a0a3..7a07003 100644 --- a/src/abstractsparsearray/SparseArraysBaseSparseArraysExt.jl +++ b/src/abstractsparsearray/SparseArraysBaseSparseArraysExt.jl @@ -1,6 +1,6 @@ using Base: Forward using SparseArrays: SparseArrays, SparseMatrixCSC, findnz, getcolptr, nonzeros, rowvals -using ..SparseArraysBase: stored_length +using SparseArraysBase: stored_length # Julia Base `AbstractSparseArray` interface SparseArrays.nnz(a::AbstractSparseArray) = stored_length(a) diff --git a/src/abstractsparsearray/arraylayouts.jl b/src/abstractsparsearray/arraylayouts.jl index 293d58f..5b9baf8 100644 --- a/src/abstractsparsearray/arraylayouts.jl +++ b/src/abstractsparsearray/arraylayouts.jl @@ -1,6 +1,6 @@ using ArrayLayouts: ArrayLayouts, Dot, DualLayout, MatMulMatAdd, MatMulVecAdd, MulAdd using LinearAlgebra: Adjoint, Transpose -using ..TypeParameterAccessors: parenttype +using TypeParameterAccessors: parenttype function ArrayLayouts.MemoryLayout(arraytype::Type{<:AnyAbstractSparseArray}) return SparseLayout() diff --git a/src/sparsearrayinterface/broadcast.jl b/src/sparsearrayinterface/broadcast.jl index d113932..cb18aa2 100644 --- a/src/sparsearrayinterface/broadcast.jl +++ b/src/sparsearrayinterface/broadcast.jl @@ -1,5 +1,5 @@ using Base.Broadcast: BroadcastStyle, AbstractArrayStyle, DefaultArrayStyle, Broadcasted -using ..BroadcastMapConversion: map_function, map_args +using BroadcastMapConversion: map_function, map_args struct SparseArrayStyle{N} <: AbstractArrayStyle{N} end diff --git a/src/sparsearrayinterface/densearray.jl b/src/sparsearrayinterface/densearray.jl index 2f4fd02..3b98c18 100644 --- a/src/sparsearrayinterface/densearray.jl +++ b/src/sparsearrayinterface/densearray.jl @@ -3,7 +3,7 @@ # about the array (such as which device it is on). # TODO: Maybe call `densecopy`? # TODO: Make sure this actually preserves the device, -# maybe use `NDTensors.TypeParameterAccessors.unwrap_array_type`. +# maybe use `TypeParameterAccessors.unwrap_array_type`. function densearray(a::AbstractArray) # TODO: `set_ndims(unwrap_array_type(a), ndims(a))(a)` # Maybe define `densetype(a) = set_ndims(unwrap_array_type(a), ndims(a))`. diff --git a/src/sparsearrayinterface/wrappers.jl b/src/sparsearrayinterface/wrappers.jl index a4fce3b..27c493f 100644 --- a/src/sparsearrayinterface/wrappers.jl +++ b/src/sparsearrayinterface/wrappers.jl @@ -1,4 +1,4 @@ -using ..NestedPermutedDimsArrays: NestedPermutedDimsArray +using NestedPermutedDimsArrays: NestedPermutedDimsArray ## PermutedDimsArray diff --git a/test/Project.toml b/test/Project.toml index d674f61..3a80c84 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -2,6 +2,8 @@ ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" -NDTensors = "23ae76d9-e61a-49c4-8f12-3f1a16adf9cf" -SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +NestedPermutedDimsArrays = "2c2a8ec4-3cfc-4276-aa3e-1307b4294e58" +SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +SparseArraysBase = "0d5efcca-f356-4864-8770-e1ed8d78f208" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/SparseArraysBaseTestUtils/AbstractSparseArrays.jl b/test/SparseArraysBaseTestUtils/AbstractSparseArrays.jl index 5ae5f5c..ccf8e32 100644 --- a/test/SparseArraysBaseTestUtils/AbstractSparseArrays.jl +++ b/test/SparseArraysBaseTestUtils/AbstractSparseArrays.jl @@ -1,6 +1,6 @@ module AbstractSparseArrays using ArrayLayouts: ArrayLayouts, MatMulMatAdd, MemoryLayout, MulAdd -using NDTensors.SparseArraysBase: SparseArraysBase, AbstractSparseArray, Zero +using SparseArraysBase: SparseArraysBase, AbstractSparseArray, Zero struct SparseArray{T,N,Zero} <: AbstractSparseArray{T,N} data::Vector{T} diff --git a/test/SparseArraysBaseTestUtils/DiagonalArrays.jl b/test/SparseArraysBaseTestUtils/DiagonalArrays.jl index 394a622..96b062c 100644 --- a/test/SparseArraysBaseTestUtils/DiagonalArrays.jl +++ b/test/SparseArraysBaseTestUtils/DiagonalArrays.jl @@ -1,5 +1,5 @@ module DiagonalArrays -using NDTensors.SparseArraysBase: SparseArraysBase +using SparseArraysBase: SparseArraysBase struct DiagonalArray{T,N} <: AbstractArray{T,N} data::Vector{T} diff --git a/test/SparseArraysBaseTestUtils/Project.toml b/test/SparseArraysBaseTestUtils/Project.toml deleted file mode 100644 index 9b1d5cc..0000000 --- a/test/SparseArraysBaseTestUtils/Project.toml +++ /dev/null @@ -1,2 +0,0 @@ -[deps] -NDTensors = "23ae76d9-e61a-49c4-8f12-3f1a16adf9cf" diff --git a/test/SparseArraysBaseTestUtils/SparseArrays.jl b/test/SparseArraysBaseTestUtils/SparseArrays.jl index 082adb1..827ce01 100644 --- a/test/SparseArraysBaseTestUtils/SparseArrays.jl +++ b/test/SparseArraysBaseTestUtils/SparseArrays.jl @@ -1,6 +1,6 @@ module SparseArrays using LinearAlgebra: LinearAlgebra -using NDTensors.SparseArraysBase: SparseArraysBase, Zero +using SparseArraysBase: SparseArraysBase, Zero struct SparseArray{T,N,Zero} <: AbstractArray{T,N} data::Vector{T} @@ -76,7 +76,7 @@ function SparseArraysBase.setindex_notstored!( end # TODO: Make this into a generic definition of all `AbstractArray`? -using NDTensors.SparseArraysBase: perm, stored_indices +using SparseArraysBase: perm, stored_indices function SparseArraysBase.stored_indices( a::PermutedDimsArray{<:Any,<:Any,<:Any,<:Any,<:SparseArray} ) @@ -86,7 +86,7 @@ function SparseArraysBase.stored_indices( end # TODO: Make this into a generic definition of all `AbstractArray`? -using NDTensors.SparseArraysBase: sparse_storage +using SparseArraysBase: sparse_storage function SparseArraysBase.sparse_storage( a::PermutedDimsArray{<:Any,<:Any,<:Any,<:Any,<:SparseArray} ) @@ -94,7 +94,7 @@ function SparseArraysBase.sparse_storage( end # TODO: Make this into a generic definition of all `AbstractArray`? -using NDTensors.NestedPermutedDimsArrays: NestedPermutedDimsArray +using NestedPermutedDimsArrays: NestedPermutedDimsArray function SparseArraysBase.stored_indices( a::NestedPermutedDimsArray{<:Any,<:Any,<:Any,<:Any,<:SparseArray} ) @@ -104,8 +104,8 @@ function SparseArraysBase.stored_indices( end # TODO: Make this into a generic definition of all `AbstractArray`? -using NDTensors.NestedPermutedDimsArrays: NestedPermutedDimsArray -using NDTensors.SparseArraysBase: sparse_storage +using NestedPermutedDimsArrays: NestedPermutedDimsArray +using SparseArraysBase: sparse_storage function SparseArraysBase.sparse_storage( a::NestedPermutedDimsArray{<:Any,<:Any,<:Any,<:Any,<:SparseArray} ) diff --git a/test/runtests.jl b/test/runtests.jl index 40340f5..f296ca0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,12 @@ @eval module $(gensym()) -for filename in ["sparsearraydok", "abstractsparsearray", "array", "diagonalarray"] - include("test_$filename.jl") +using Test: @testset + +@testset "SparseArraysBase.jl" begin + filenames = filter(readdir(@__DIR__)) do f + startswith("test_")(f) && endswith(".jl")(f) + end + @testset "Test $filename" for filename in filenames + include(filename) + end end end diff --git a/test/test_abstractsparsearray.jl b/test/test_abstractsparsearray.jl index b64955c..7cc7c2f 100644 --- a/test/test_abstractsparsearray.jl +++ b/test/test_abstractsparsearray.jl @@ -1,7 +1,7 @@ @eval module $(gensym()) using LinearAlgebra: dot, mul!, norm -using NDTensors.SparseArraysBase: SparseArraysBase -using NDTensors.NestedPermutedDimsArrays: NestedPermutedDimsArray +using SparseArraysBase: SparseArraysBase +using NestedPermutedDimsArrays: NestedPermutedDimsArray include("SparseArraysBaseTestUtils/SparseArraysBaseTestUtils.jl") using .SparseArraysBaseTestUtils.AbstractSparseArrays: AbstractSparseArrays using .SparseArraysBaseTestUtils.SparseArrays: SparseArrays diff --git a/test/test_array.jl b/test/test_array.jl index 0037412..8306eef 100644 --- a/test/test_array.jl +++ b/test/test_array.jl @@ -1,5 +1,5 @@ @eval module $(gensym()) -using NDTensors.SparseArraysBase: SparseArraysBase +using SparseArraysBase: SparseArraysBase include("SparseArraysBaseTestUtils/SparseArraysBaseTestUtils.jl") using Test: @test, @testset @testset "Array (eltype=$elt)" for elt in (Float32, ComplexF32, Float64, ComplexF64) diff --git a/test/test_diagonalarray.jl b/test/test_diagonalarray.jl index 18075e3..59bc470 100644 --- a/test/test_diagonalarray.jl +++ b/test/test_diagonalarray.jl @@ -1,6 +1,6 @@ @eval module $(gensym()) using LinearAlgebra: norm -using NDTensors.SparseArraysBase: SparseArraysBase +using SparseArraysBase: SparseArraysBase include("SparseArraysBaseTestUtils/SparseArraysBaseTestUtils.jl") using .SparseArraysBaseTestUtils.DiagonalArrays: DiagonalArray using Test: @test, @testset, @test_throws diff --git a/test/test_sparsearraydok.jl b/test/test_sparsearraydok.jl index 92afb06..eb43f28 100644 --- a/test/test_sparsearraydok.jl +++ b/test/test_sparsearraydok.jl @@ -7,9 +7,8 @@ using Dictionaries: Dictionary using Test: @test, @testset, @test_broken -using NDTensors.SparseArraysBase: - SparseArraysBase, SparseArrayDOK, SparseMatrixDOK, @maybe_grow -using NDTensors.SparseArraysBase: storage_indices, stored_length +using SparseArraysBase: SparseArraysBase, SparseArrayDOK, SparseMatrixDOK, @maybe_grow +using SparseArraysBase: storage_indices, stored_length using SparseArrays: SparseMatrixCSC, nnz @testset "SparseArrayDOK (eltype=$elt)" for elt in (Float32, ComplexF32, Float64, ComplexF64)