Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b75f7d8
DArray: Use Finch for sparse arrays
jpsamaroo Oct 21, 2025
8712090
DArray: Add matmul sparse support
jpsamaroo Apr 22, 2024
b8474b4
DArray: Add spzeros/fspzeros
jpsamaroo Oct 28, 2025
a652577
sparse: Fix similar allocation
jpsamaroo Nov 26, 2025
aa79903
test: Allow --test with directory
jpsamaroo Jun 3, 2026
2b13488
DArray: Add view(A, AutoBlocks()) and fill!
jpsamaroo Jun 3, 2026
95d7878
DArray/sparse: Improve copy/indexing and aliasing
jpsamaroo Jun 4, 2026
1ce1ed2
DArray/sparse: Fix sparse matmul implementations
jpsamaroo Jun 4, 2026
ce4b17c
test: Add explicit Finch/SparseArrays matmul tests
jpsamaroo Jun 4, 2026
82059d3
DArray/sparse: Remove global sparse mode switch
jpsamaroo Jun 6, 2026
0bee29f
SparseArrays: Lightly optimize matmul kernel
jpsamaroo Jun 6, 2026
57c1c00
Datadeps/sparse: Ignore array wrappers for objects like DSparseMatrix
jpsamaroo Jun 6, 2026
68f4f3e
test/sparse: Only run Finch tests on demand
jpsamaroo Jun 7, 2026
f94c437
DArray/sparse: DSparseMatrix->DSparseArray, and add matrix-vector pro…
jpsamaroo Jun 7, 2026
98a7eaf
DArray/sparse: Add iterative solvers via Krylov.jl
jpsamaroo Jun 7, 2026
899b8bf
DArray/sparse: Add AMG and ILU preconditioner integrations
jpsamaroo Jun 8, 2026
79068a6
DArray/sparse: Add sparse direct solvers (KLU/UMFPACK)
jpsamaroo Jul 24, 2026
4f25ed5
docs: Document sparse DArrays
jpsamaroo Jul 24, 2026
2b5d3a4
MPIExt: Declare SparseArrays as an extension dependency
jpsamaroo Jul 24, 2026
100c33f
test/mpienv: Add SparseArrays so MPIExt can load
jpsamaroo Jul 24, 2026
b31fdb6
DArray/sparse: Add GPU sparse tile support (CUDA/ROC/OpenCL/Metal/one…
jpsamaroo Jul 25, 2026
9a8c22d
DArray/sparse: Add GPU sparse Krylov solver tests
jpsamaroo Jul 25, 2026
b801cec
Datadeps: Drop unsound arg_current write-back elision
jpsamaroo Jul 24, 2026
beb8a2f
DArray: Base.fetch(::DArray) just converts DTask to Chunk
jpsamaroo Jul 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,17 @@ steps:
julia --project=test/metalenv -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
julia --project=test/metalenv test/run_mpi.jl 2 2 test/mpi_metal.jl

- label: Julia 1.11 (Finch)
timeout_in_minutes: 90
if: build.message !~ /\[skip tests\]/
plugins:
- JuliaCI/julia#v1:
version: "1.11"
- JuliaCI/julia-test#v1: ~
- JuliaCI/julia-coverage#v1:
codecov: true
env:
CI_TEST_FINCH: "1"

# env:
# SECRET_CODECOV_TOKEN: ""
31 changes: 29 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Requires = "ae029012-a4dd-5104-9daa-d747884805df"
ScopedValues = "7e506255-f358-4e82-b7e4-beb19740aa63"
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
TaskLocalValues = "ed4db957-447d-4319-bfb6-7fa9ae7ecf34"
Expand All @@ -33,63 +32,91 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
[weakdeps]
AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"
AlgebraicMultigrid = "2169fc97-5a83-5252-b627-83903c6c433c"
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
Finch = "9177782c-1635-4eb9-9bfb-d9dfa25e6bce"
IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895"
GraphViz = "f526b714-d49f-11e8-06ff-31ed36ee7ee0"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
Krylov = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7"
LinuxPerf = "b4c46c6c-4fb0-484d-a11a-41bc3392d094"
MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
Metal = "dde4c033-4e86-420c-a63e-0dd931031962"
Metis = "2679e427-3c69-5b7f-982b-ece356f1e94b"
OpenCL = "08131aa3-fb12-5dee-8b74-c09406e224a2"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PureKLU = "0c0d3e7f-3a8b-4f7e-b6f1-9a4d2e7c1f01"
PureUMFPACK = "b7e1f0a2-3c4d-4e5f-9a0b-1c2d3e4f5a6b"
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
oneAPI = "8f75cd03-7ff8-4ecb-9b8f-daf728133b1b"

[extensions]
AbstractFFTsExt = "AbstractFFTs"
AlgebraicMultigridExt = ["AlgebraicMultigrid", "SparseArrays"]
CUDAExt = "CUDA"
CUDASparseArraysExt = ["CUDA", "SparseArrays"]
DistributionsExt = "Distributions"
FinchExt = "Finch"
GraphVizExt = "GraphViz"
GraphVizSimpleExt = "Colors"
IncompleteLUExt = ["IncompleteLU", "SparseArrays"]
IntelExt = "oneAPI"
IntelSparseArraysExt = ["oneAPI", "SparseArrays"]
JSON3Ext = "JSON3"
KrylovExt = "Krylov"
LinuxPerfExt = "LinuxPerf"
MPIExt = "MPI"
MPIExt = ["MPI", "SparseArrays"]
MetalExt = "Metal"
MetalSparseArraysExt = ["Metal", "SparseArrays"]
MetisExt = ["Metis", "SparseArrays"]
OpenCLExt = "OpenCL"
OpenCLSparseArraysExt = ["OpenCL", "SparseArrays"]
PlotsExt = ["DataFrames", "Plots"]
PureKLUExt = ["PureKLU", "SparseArrays"]
PureUMFPACKExt = ["PureUMFPACK", "SparseArrays"]
PythonExt = "PythonCall"
ROCExt = "AMDGPU"
ROCSparseArraysExt = ["AMDGPU", "SparseArrays"]
SparseArraysExt = "SparseArrays"

[compat]
AMDGPU = "1, 2"
AbstractFFTs = "1.5.0"
Adapt = "4"
AlgebraicMultigrid = "1"
CUDA = "3, 4, 5"
Colors = "0.12, 0.13"
DataFrames = "1"
DataStructures = "0.18, 0.19"
DistributedNext = "1.0.0"
Distributions = "0.25"
FillArrays = "1.13.0"
Finch = "1.2.9"
GPUArraysCore = "0.2.0"
GraphViz = "0.2"
Graphs = "1"
IncompleteLU = "0.2"
JSON3 = "1"
KernelAbstractions = "0.9"
Krylov = "0.10"
LinuxPerf = "0.4.2"
MPI = "0.20.22"
MacroTools = "0.5"
MemPool = "0.4.17"
Metal = "1.1"
Metis = "1"
NextLA = "0.2.2"
OnlineStats = "1"
OpenCL = "0.10"
Plots = "1"
PrecompileTools = "1.2"
Preferences = "1.4.3"
PureKLU = "1"
PureUMFPACK = "0.1"
PythonCall = "0.9"
Requires = "1"
ScopedValues = "1.1"
Expand Down
2 changes: 2 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ makedocs(;
"Task Affinity" => "task-affinity.md",
"Data Management" => "data-management.md",
"Distributed Arrays" => "darray.md",
"Sparse Arrays" => "sparse-arrays.md",
"Iterative Solvers" => "iterative-solving.md",
"Streaming Tasks" => "streaming.md",
"Scopes" => "scopes.md",
"Processors" => "processors.md",
Expand Down
70 changes: 70 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,76 @@ collect(DA) # returns a `Matrix{Float64}`

-----

## Quickstart: Sparse Arrays

A `DArray` can hold sparse tiles, giving a distributed, tiled sparse matrix.
Load a sparse backend (`SparseArrays`) to enable it.

For more details: [Sparse Distributed Arrays](@ref)

### Distribute or allocate a sparse `DArray`

```julia
using SparseArrays

# Partition an existing sparse matrix into sparse tiles
DA = distribute(sprand(1000, 1000, 0.01), Blocks(250, 250))

# Or allocate sparse DArrays directly
Z = spzeros(Blocks(250, 250), Float64, 1000, 1000)
R = sprand(Blocks(250, 250), Float64, (1000, 1000), 0.01)
```

### Multiply sparse arrays

```julia
using LinearAlgebra
x = distribute(rand(1000), Blocks(250))
y = DA * x # distributed sparse matrix-vector multiply (dense result)
C = DA * DA # distributed sparse-sparse matmul (sparse result)
```

`collect(DA)` returns a dense `Array`; operate on the `DArray` to stay sparse.

-----

## Quickstart: Iterative Solvers

Dagger provides distributed, matrix-free Krylov solvers (`cg`, `minres`,
`gmres`, `bicgstab`) for `A x = b`. Load `Krylov` to enable them.

For more details: [Iterative Solvers](@ref)

### Solve a sparse system

```julia
using SparseArrays, Krylov, LinearAlgebra

n = 1000
A = spdiagm(-1 => fill(-1.0, n-1), 0 => fill(2.0, n), 1 => fill(-1.0, n-1))
DA = distribute(A, Blocks(250, 250)) # square tiles
b = distribute(rand(n), Blocks(250))

x, stats = Dagger.cg(DA, b)
@show stats.solved, stats.niter
```

### Add a preconditioner

```julia
using AlgebraicMultigrid # enables Dagger.AMGPreconditioner

P = Dagger.AMGPreconditioner(DA) # build once
x, stats = Dagger.cg(DA, b; M = P) # pass as `M`
```

Other preconditioners: `Dagger.JacobiPreconditioner`,
`Dagger.BlockJacobiPreconditioner` (core), and `Dagger.BlockILUPreconditioner`
(load `IncompleteLU`). Any object implementing `mul!(y, A, x)` over `DVector`s
can be used as a matrix-free operator `A`.

-----

## Quickstart: Stencil Operations

Dagger's `@stencil` macro allows for easy specification of stencil operations on `DArray`s, often used in simulations and image processing. These operations typically involve updating an element based on the values of its neighbors.
Expand Down
Loading
Loading