Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Copilot Instructions for DeviceSparseArrays.jl
# Copilot Instructions for GenericSparseArrays.jl

These guidelines give AI coding agents the minimum project-specific context to be productive. They reflect the repository as it exists now and should NOT assume unimplemented features.

## 1. Purpose & Current State
- Package name: `DeviceSparseArrays` — intended focus: backend-agnostic sparse array types & operations for CPU/GPU/accelerators.
- Package name: `GenericSparseArrays` — intended focus: backend-agnostic sparse array types & operations for CPU/GPU/accelerators.
- Unlike traditional SparseArrays.jl, this package aims to provide a unified interface for sparse data structures that can seamlessly operate across different hardware backends.
- Any new functionality you add must be inside this module and accompanied by tests + docstrings.

## 2. Repository Layout
- `Project.toml` / `Manifest.toml`: Project environment. Add deps with compat bounds in alphabetical order; do not remove existing `[compat]` or test extras.
- `src/DeviceSparseArrays.jl`: Single entry point. Keep exports explicit (add an `export` block when you introduce public APIs). Keep imports explicit (use `import PackageName: symbol` or `using PackageName: symbol` as needed).
- `src/GenericSparseArrays.jl`: Single entry point. Keep exports explicit (add an `export` block when you introduce public APIs). Keep imports explicit (use `import PackageName: symbol` or `using PackageName: symbol` as needed).
- `docs/` (Documenter): `make.jl` sets up docs + doctests. `docs/src/index.md` auto-docs the module; adding docstrings automatically surfaces them.

## 3. Development Workflows
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@ jobs:
shell: julia --project=docs --color=yes {0}
run: |
using Documenter: DocMeta, doctest
using DeviceSparseArrays
DocMeta.setdocmeta!(DeviceSparseArrays, :DocTestSetup, :(using DeviceSparseArrays); recursive=true)
doctest(DeviceSparseArrays)
using GenericSparseArrays
DocMeta.setdocmeta!(GenericSparseArrays, :DocTestSetup, :(using GenericSparseArrays); recursive=true)
doctest(GenericSparseArrays)
4 changes: 2 additions & 2 deletions GEMINI.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Gemini Project Context: DeviceSparseArrays.jl
# Gemini Project Context: GenericSparseArrays.jl

## Project Overview

`DeviceSparseArrays.jl` is a Julia package that provides backend-agnostic sparse array types and operations for CPUs, GPUs, and other accelerators. It aims to offer a unified interface for sparse data structures that can seamlessly operate across different hardware backends.
`GenericSparseArrays.jl` is a Julia package that provides backend-agnostic sparse array types and operations for CPUs, GPUs, and other accelerators. It aims to offer a unified interface for sparse data structures that can seamlessly operate across different hardware backends.

The package supports various sparse formats like CSC, CSR, and COO, and can be used with backends such as:
- CPU (standard Julia arrays)
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name = "DeviceSparseArrays"
name = "GenericSparseArrays"
uuid = "da3fe0eb-88a8-4d14-ae1a-857c283e9c70"
authors = ["Alberto Mercurio <alberto.mercurio96@gmail.com> and contributors"]
version = "0.1.0"
Expand All @@ -15,7 +15,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb"

[extensions]
DeviceSparseArraysJLArraysExt = "JLArrays"
GenericSparseArraysJLArraysExt = "JLArrays"

[compat]
AcceleratedKernels = "0.4"
Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# DeviceSparseArrays
# GenericSparseArrays

[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://albertomercurio.github.io/DeviceSparseArrays.jl/stable/)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://albertomercurio.github.io/DeviceSparseArrays.jl/dev/)
[![Build Status](https://github.com/albertomercurio/DeviceSparseArrays.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/albertomercurio/DeviceSparseArrays.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Coverage](https://codecov.io/gh/albertomercurio/DeviceSparseArrays.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/albertomercurio/DeviceSparseArrays.jl)
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://albertomercurio.github.io/GenericSparseArrays.jl/stable/)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://albertomercurio.github.io/GenericSparseArrays.jl/dev/)
[![Build Status](https://github.com/albertomercurio/GenericSparseArrays.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/albertomercurio/GenericSparseArrays.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Coverage](https://codecov.io/gh/albertomercurio/GenericSparseArrays.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/albertomercurio/GenericSparseArrays.jl)
[![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)
[![Benchmarks](https://github.com/albertomercurio/DeviceSparseArrays.jl/actions/workflows/Benchmarks.yml/badge.svg?branch=main)](https://albertomercurio.github.io/DeviceSparseArrays.jl/benchmarks/)
[![Benchmarks](https://github.com/albertomercurio/GenericSparseArrays.jl/actions/workflows/Benchmarks.yml/badge.svg?branch=main)](https://albertomercurio.github.io/GenericSparseArrays.jl/benchmarks/)
[![code style: runic][runic-img]][runic-url]

[runic-img]: https://img.shields.io/badge/code_style-%E1%9A%B1%E1%9A%A2%E1%9A%BE%E1%9B%81%E1%9A%B2-black
[runic-url]: https://github.com/fredrikekre/Runic.jl

DeviceSparseArrays.jl is a Julia package that provides backend-agnostic sparse array types and operations for CPU, GPU, and other accelerators. It aims to offer a unified interface for sparse data structures that can seamlessly operate across different hardware backends. For example, a `DeviceSparseMatrixCSC` type could represent a sparse matrix stored in Compressed Sparse Column format, where the underlying data could reside in CPU, GPU, or any other memory type, dispatching specific implementations based on the target device. This allows users to write code that is portable and efficient across various hardware platforms without needing to change their code for different backends. The aim of the package is to support a wide range of different sparse formats (e.g., CSC, CSR, COO) as well as different backends like:
GenericSparseArrays.jl is a Julia package that provides backend-agnostic sparse array types and operations for CPU, GPU, and other accelerators. It aims to offer a unified interface for sparse data structures that can seamlessly operate across different hardware backends. For example, a `GenericSparseMatrixCSC` type could represent a sparse matrix stored in Compressed Sparse Column format, where the underlying data could reside in CPU, GPU, or any other memory type, dispatching specific implementations based on the target device. This allows users to write code that is portable and efficient across various hardware platforms without needing to change their code for different backends. The aim of the package is to support a wide range of different sparse formats (e.g., CSC, CSR, COO) as well as different backends like:
- CPU (using standard Julia arrays)
- GPU (using [CUDA.jl](https://github.com/JuliaGPU/CUDA.jl), [AMDGPU.jl](https://github.com/JuliaGPU/AMDGPU.jl), [oneAPI.jl](https://github.com/JuliaGPU/oneAPI.jl), [Metal.jl](https://github.com/JuliaGPU/Metal.jl), etc.)
- [DistributedArrays.jl](https://github.com/JuliaParallel/DistributedArrays.jl) (for distributed computing)
Expand All @@ -28,23 +28,23 @@ The package aims to use [KernelAbstractions.jl](https://github.com/JuliaGPU/Kern
You can install the package using Julia's package manager. In the Julia REPL, run:
```julia
using Pkg
Pkg.add(url="https://github.com/albertomercurio/DeviceSparseArrays.jl")
Pkg.add(url="https://github.com/albertomercurio/GenericSparseArrays.jl")
```

## Usage Examples

### Basic Usage with CSC Matrices

```julia
using DeviceSparseArrays
using GenericSparseArrays
using SparseArrays
using LinearAlgebra

# Create a 100x80 sparse matrix with 10% sparsity
A_sparse = sprand(Float64, 100, 80, 0.1)

# Convert to DeviceSparseMatrixCSC (CPU by default)
A_device = DeviceSparseMatrixCSC(A_sparse)
# Convert to GenericSparseMatrixCSC (CPU by default)
A_device = GenericSparseMatrixCSC(A_sparse)

# Create a vector for matrix-vector multiplication
b = rand(Float64, 80)
Expand Down Expand Up @@ -86,7 +86,7 @@ c_reactant = A_reactant * b_reactant
```julia
# Create a sparse matrix and convert to CSR format
A_sparse = sprand(Float64, 100, 80, 0.1) # 100x80 matrix with 10% sparsity
A_csr = DeviceSparseMatrixCSR(A_sparse)
A_csr = GenericSparseMatrixCSR(A_sparse)

# Convert to different backends
A_csr_cuda = adapt(CuArray, A_csr)
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
DeviceSparseArrays = "da3fe0eb-88a8-4d14-ae1a-857c283e9c70"
GenericSparseArrays = "da3fe0eb-88a8-4d14-ae1a-857c283e9c70"
JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb"
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
8 changes: 4 additions & 4 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# DeviceSparseArrays.jl Benchmarks
# GenericSparseArrays.jl Benchmarks

This directory contains benchmark tracking for the DeviceSparseArrays.jl package using [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl) and [github-action-benchmark](https://github.com/benchmark-action/github-action-benchmark).
This directory contains benchmark tracking for the GenericSparseArrays.jl package using [BenchmarkTools.jl](https://github.com/JuliaCI/BenchmarkTools.jl) and [github-action-benchmark](https://github.com/benchmark-action/github-action-benchmark).

## Structure

Expand Down Expand Up @@ -75,7 +75,7 @@ The workflow:
## Viewing Benchmark Results

Benchmark results are tracked over time and can be viewed at:
https://albertomercurio.github.io/DeviceSparseArrays.jl/benchmarks/
https://albertomercurio.github.io/GenericSparseArrays.jl/benchmarks/

## Adding New Benchmarks

Expand All @@ -87,7 +87,7 @@ To add new benchmarks:
function benchmark_new_feature!(SUITE, array_constructor, array_type_name; N=10000, T=Float64)
# Create test data using sprand
data = sprand(T, N, N, 0.05)
adapted_data = adapt(array_constructor, DeviceSparseMatrix...(data))
adapted_data = adapt(array_constructor, GenericSparseMatrix...(data))

# Add to suite
group_name = "Feature Name"
Expand Down
10 changes: 5 additions & 5 deletions benchmarks/benchmark_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ This function uses multiple dispatch to handle different array types:
# Examples
```julia
# GPU array with KernelAbstractions - will synchronize
gpu_arr = adapt(CuArray, DeviceSparseVector(...))
gpu_arr = adapt(CuArray, GenericSparseVector(...))
_synchronize_backend(gpu_arr)

# CPU array or arrays without KernelAbstractions - no-op
cpu_arr = DeviceSparseVector(...)
cpu_arr = GenericSparseVector(...)
_synchronize_backend(cpu_arr)

# Extend for custom array types:
Expand All @@ -28,11 +28,11 @@ _synchronize_backend(cpu_arr)
_synchronize_backend(arr) = nothing # Fallback: no-op for arrays without KernelAbstractions

"""
_synchronize_backend(arr::AbstractDeviceSparseArray)
_synchronize_backend(arr::AbstractGenericSparseArray)

Synchronize KernelAbstractions backend for DeviceSparseArray types.
Synchronize KernelAbstractions backend for GenericSparseArray types.
"""
_synchronize_backend(arr::AbstractDeviceSparseArray) = _synchronize_backend(nonzeros(arr))
_synchronize_backend(arr::AbstractGenericSparseArray) = _synchronize_backend(nonzeros(arr))

function _synchronize_backend(x::AbstractArray)
backend = KernelAbstractions.get_backend(x)
Expand Down
14 changes: 7 additions & 7 deletions benchmarks/conversion_benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ function benchmark_conversions!(
sm_csc_std = sprand(T, N, N, 0.01)

# Convert to different formats
sm_csc = DeviceSparseMatrixCSC(sm_csc_std)
sm_csr = DeviceSparseMatrixCSR(sm_csc_std)
sm_coo = DeviceSparseMatrixCOO(sm_csc_std)
sm_csc = GenericSparseMatrixCSC(sm_csc_std)
sm_csr = GenericSparseMatrixCSR(sm_csc_std)
sm_coo = GenericSparseMatrixCOO(sm_csc_std)

# Adapt to device
dsm_csc = adapt(array_constructor, sm_csc)
Expand All @@ -34,25 +34,25 @@ function benchmark_conversions!(

# CSC → COO conversion
SUITE["Format Conversions"][array_type_name]["CSC → COO"] = @benchmarkable begin
DeviceSparseMatrixCOO($dsm_csc)
GenericSparseMatrixCOO($dsm_csc)
_synchronize_backend($dsm_csc)
end

# COO → CSC conversion
SUITE["Format Conversions"][array_type_name]["COO → CSC"] = @benchmarkable begin
DeviceSparseMatrixCSC($dsm_coo)
GenericSparseMatrixCSC($dsm_coo)
_synchronize_backend($dsm_coo)
end

# CSR → COO conversion
SUITE["Format Conversions"][array_type_name]["CSR → COO"] = @benchmarkable begin
DeviceSparseMatrixCOO($dsm_csr)
GenericSparseMatrixCOO($dsm_csr)
_synchronize_backend($dsm_csr)
end

# COO → CSR conversion
SUITE["Format Conversions"][array_type_name]["COO → CSR"] = @benchmarkable begin
DeviceSparseMatrixCSR($dsm_coo)
GenericSparseMatrixCSR($dsm_coo)
_synchronize_backend($dsm_coo)
end

Expand Down
48 changes: 24 additions & 24 deletions benchmarks/matrix_benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ function benchmark_matrix_vector_mul!(
sm_csc_std = sprand(T, N, N, 0.01)

# Convert to different formats
sm_csc = DeviceSparseMatrixCSC(sm_csc_std)
sm_csr = DeviceSparseMatrixCSR(sm_csc_std)
sm_coo = DeviceSparseMatrixCOO(sm_csc_std)
sm_csc = GenericSparseMatrixCSC(sm_csc_std)
sm_csr = GenericSparseMatrixCSR(sm_csc_std)
sm_coo = GenericSparseMatrixCOO(sm_csc_std)

# Adapt to device
dsm_csc = adapt(array_constructor, sm_csc)
Expand Down Expand Up @@ -83,9 +83,9 @@ function benchmark_matrix_matrix_mul!(
sm_csc_std = sprand(T, N, N, 0.01)

# Convert to different formats
sm_csc = DeviceSparseMatrixCSC(sm_csc_std)
sm_csr = DeviceSparseMatrixCSR(sm_csc_std)
sm_coo = DeviceSparseMatrixCOO(sm_csc_std)
sm_csc = GenericSparseMatrixCSC(sm_csc_std)
sm_csr = GenericSparseMatrixCSR(sm_csc_std)
sm_coo = GenericSparseMatrixCOO(sm_csc_std)

# Adapt to device
dsm_csc = adapt(array_constructor, sm_csc)
Expand Down Expand Up @@ -140,9 +140,9 @@ function benchmark_three_arg_dot!(
sm_csc_std = sprand(T, N, N, 0.01)

# Convert to different formats
sm_csc = DeviceSparseMatrixCSC(sm_csc_std)
sm_csr = DeviceSparseMatrixCSR(sm_csc_std)
sm_coo = DeviceSparseMatrixCOO(sm_csc_std)
sm_csc = GenericSparseMatrixCSC(sm_csc_std)
sm_csr = GenericSparseMatrixCSR(sm_csc_std)
sm_coo = GenericSparseMatrixCOO(sm_csc_std)

# Adapt to device
dsm_csc = adapt(array_constructor, sm_csc)
Expand Down Expand Up @@ -197,9 +197,9 @@ function benchmark_sparse_dense_add!(
sm_csc_std = sprand(T, N, N, 0.01)

# Convert to different formats
sm_csc = DeviceSparseMatrixCSC(sm_csc_std)
sm_csr = DeviceSparseMatrixCSR(sm_csc_std)
sm_coo = DeviceSparseMatrixCOO(sm_csc_std)
sm_csc = GenericSparseMatrixCSC(sm_csc_std)
sm_csr = GenericSparseMatrixCSR(sm_csc_std)
sm_coo = GenericSparseMatrixCOO(sm_csc_std)

# Adapt to device
dsm_csc = adapt(array_constructor, sm_csc)
Expand Down Expand Up @@ -254,12 +254,12 @@ function benchmark_sparse_sparse_add!(
sm_b_csc_std = sprand(T, N, N, 0.01)

# Convert to different formats
sm_a_csc = DeviceSparseMatrixCSC(sm_a_csc_std)
sm_b_csc = DeviceSparseMatrixCSC(sm_b_csc_std)
sm_a_csr = DeviceSparseMatrixCSR(sm_a_csc_std)
sm_b_csr = DeviceSparseMatrixCSR(sm_b_csc_std)
sm_a_coo = DeviceSparseMatrixCOO(sm_a_csc_std)
sm_b_coo = DeviceSparseMatrixCOO(sm_b_csc_std)
sm_a_csc = GenericSparseMatrixCSC(sm_a_csc_std)
sm_b_csc = GenericSparseMatrixCSC(sm_b_csc_std)
sm_a_csr = GenericSparseMatrixCSR(sm_a_csc_std)
sm_b_csr = GenericSparseMatrixCSR(sm_b_csc_std)
sm_a_coo = GenericSparseMatrixCOO(sm_a_csc_std)
sm_b_coo = GenericSparseMatrixCOO(sm_b_csc_std)

# Adapt to device
dsm_a_csc = adapt(array_constructor, sm_a_csc)
Expand Down Expand Up @@ -308,14 +308,14 @@ function benchmark_kron!(SUITE, array_constructor, array_type_name; N = 100, T =
sm_b_std = sprand(T, N, N, 0.01)

# Convert to different formats
sm_a_csc = DeviceSparseMatrixCSC(sm_a_std)
sm_b_csc = DeviceSparseMatrixCSC(sm_b_std)
sm_a_csc = GenericSparseMatrixCSC(sm_a_std)
sm_b_csc = GenericSparseMatrixCSC(sm_b_std)

sm_a_csr = DeviceSparseMatrixCSR(sm_a_std)
sm_b_csr = DeviceSparseMatrixCSR(sm_b_std)
sm_a_csr = GenericSparseMatrixCSR(sm_a_std)
sm_b_csr = GenericSparseMatrixCSR(sm_b_std)

sm_a_coo = DeviceSparseMatrixCOO(sm_a_std)
sm_b_coo = DeviceSparseMatrixCOO(sm_b_std)
sm_a_coo = GenericSparseMatrixCOO(sm_a_std)
sm_b_coo = GenericSparseMatrixCOO(sm_b_std)

# Adapt to device
dsm_a_csc = adapt(array_constructor, sm_a_csc)
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/runbenchmarks.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using BenchmarkTools
using LinearAlgebra
using SparseArrays
using DeviceSparseArrays
using GenericSparseArrays
using Adapt
using JLArrays
using KernelAbstractions
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/vector_benchmarks.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function benchmark_vector_sum!(
)
# Create sparse vector with 1% density
sv = sprand(T, N, 0.01)
dsv = adapt(array_constructor, DeviceSparseVector(sv))
dsv = adapt(array_constructor, GenericSparseVector(sv))

# Level 3: Specific operation (will be plotted together)
SUITE["Sparse Vector"][array_type_name]["Sum"] = @benchmarkable begin
Expand Down Expand Up @@ -55,7 +55,7 @@ function benchmark_vector_sparse_dense_dot!(
)
# Create sparse vector with 1% density
sv = sprand(T, N, 0.01)
dsv = adapt(array_constructor, DeviceSparseVector(sv))
dsv = adapt(array_constructor, GenericSparseVector(sv))

# Create dense vector
dense_vec = adapt(array_constructor, randn(T, N))
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
DeviceSparseArrays = "da3fe0eb-88a8-4d14-ae1a-857c283e9c70"
GenericSparseArrays = "da3fe0eb-88a8-4d14-ae1a-857c283e9c70"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
JLArrays = "27aeb0d3-9eb9-45fb-866b-73c2ecf80fcb"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand Down
14 changes: 7 additions & 7 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
using DeviceSparseArrays
using GenericSparseArrays
using Documenter

DocMeta.setdocmeta!(
DeviceSparseArrays,
GenericSparseArrays,
:DocTestSetup,
:(using DeviceSparseArrays);
:(using GenericSparseArrays);
recursive = true,
)

makedocs(;
modules = [DeviceSparseArrays],
modules = [GenericSparseArrays],
authors = "Alberto Mercurio <alberto.mercurio96@gmail.com> and contributors",
sitename = "DeviceSparseArrays.jl",
sitename = "GenericSparseArrays.jl",
format = Documenter.HTML(;
canonical = "https://albertomercurio.github.io/DeviceSparseArrays.jl",
canonical = "https://albertomercurio.github.io/GenericSparseArrays.jl",
edit_link = "main",
assets = String[],
),
pages = ["Home" => "index.md", "API Reference" => "api.md"],
)

deploydocs(; repo = "github.com/albertomercurio/DeviceSparseArrays.jl", devbranch = "main")
deploydocs(; repo = "github.com/albertomercurio/GenericSparseArrays.jl", devbranch = "main")
Loading
Loading