Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sparse algebra support with OOP API #760

Open
wants to merge 98 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
5d0ff52
sparse API 1st commit
jalvesz Jan 9, 2024
b1dcbf6
Merge branch 'fortran-lang:master' into sparse
jalvesz Jan 10, 2024
c63c0dd
cmake build
jalvesz Jan 10, 2024
d940ebd
Merge branch 'sparse' of https://github.com/jalvesz/stdlib into sparse
jalvesz Jan 10, 2024
72481be
add data accessors set and get
jalvesz Jan 11, 2024
a7cb6be
fix typo
jalvesz Jan 11, 2024
d48dde5
change ij accessor as subroutine
jalvesz Jan 12, 2024
93c5c3a
Merge branch 'fortran-lang:master' into sparse
jalvesz Jan 28, 2024
6241ca3
fix missing i,j integer declaration
jalvesz Jan 29, 2024
0f2ee3b
Merge branch 'fortran-lang:master' into sparse
jalvesz Feb 9, 2024
c1a85c4
Merge branch 'fortran-lang:master' into sparse
jalvesz Mar 31, 2024
2606691
Merge branch 'fortran-lang:master' into sparse
jalvesz Apr 9, 2024
c34ac70
Merge branch 'fortran-lang:master' into sparse
jalvesz Apr 23, 2024
3126d16
Merge branch 'fortran-lang:master' into sparse
jalvesz Apr 27, 2024
c0bbabb
Merge branch 'fortran-lang:master' into sparse
jalvesz May 3, 2024
2c2431d
add comments and change _t for _type
jalvesz May 3, 2024
d64a045
revert matvec convention to (matrix,x,y)
jalvesz May 3, 2024
6786859
Merge branch 'fortran-lang:master' into sparse
jalvesz May 11, 2024
d926581
Merge branch 'fortran-lang:master' into sparse
jalvesz May 18, 2024
22b477c
Merge branch 'sparse' of https://github.com/jalvesz/stdlib into sparse
jalvesz May 18, 2024
d165b8b
upgrade sparse support with SELLC format and more tests add suffix fo…
jalvesz May 18, 2024
8f72559
include alpha and beta parameters in sparse matvec
jalvesz May 21, 2024
87c867a
wrong ellpack size
jalvesz May 25, 2024
59fe24e
start sparse specs
jalvesz May 25, 2024
43ab25f
fix module name
jalvesz May 25, 2024
838b159
include reference
jalvesz May 25, 2024
c74ad09
add matvec specs
jalvesz May 26, 2024
14bfef9
start adding conversions specs
jalvesz May 26, 2024
23be647
breaking change: rename matvec to spmv for consistency with stdlib bl…
jalvesz May 27, 2024
1d9dabc
Merge branch 'fortran-lang:master' into sparse
jalvesz May 27, 2024
8278f38
Merge branch 'fortran-lang:master' into sparse
jalvesz May 28, 2024
87bfd10
Merge branch 'fortran-lang:master' into sparse
jalvesz Jun 1, 2024
3fa318b
Merge branch 'fortran-lang:master' into sparse
jalvesz Jun 7, 2024
4aae5b4
Merge branch 'fortran-lang:master' into sparse
jalvesz Jun 10, 2024
14e9be0
Merge branch 'fortran-lang:master' into sparse
jalvesz Jun 14, 2024
6e679f5
change storage identifier names
jalvesz Jun 14, 2024
91e619a
add example with conversion and spmv
jalvesz Jun 14, 2024
7117d16
fix example path
jalvesz Jun 14, 2024
5b0aadf
make example runnable with cmake
jalvesz Jun 15, 2024
c0438f0
update spec
jalvesz Jun 15, 2024
e18b3fc
add coo2ordered procedure
jalvesz Jun 15, 2024
79534b3
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
5f35174
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
b3de016
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
181760b
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
147a5c9
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
c832eeb
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
22a70b1
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
9223345
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
827a1ef
Update doc/specs/stdlib_sparse.md
jalvesz Jun 19, 2024
21a8547
change get_value to function and add NaN if out of bounds
jalvesz Jun 19, 2024
da9f171
change is ordered by is_sorted
jalvesz Jun 19, 2024
1cbb982
remove unused base attribute
jalvesz Jun 19, 2024
a3c155a
forgotten base attribute
jalvesz Jun 20, 2024
2fb4e83
make set/get non_overridable
jalvesz Jun 21, 2024
e78c026
replace quicksort 1D by stdlib sort
jalvesz Jun 23, 2024
f25e07d
Setter procedure name change to 'add' covering scalar and array data
jalvesz Jun 27, 2024
c7035c9
add sparse test for add or getting values
jalvesz Jun 27, 2024
82950e0
change name of value retrival function to at
jalvesz Jun 27, 2024
93c1e55
sellc add/at
jalvesz Jun 28, 2024
c1f30f6
refactoring to enable a from_ijv initialization interface
jalvesz Jun 29, 2024
4c16f4a
fix module procedure attribute
jalvesz Jun 29, 2024
944212d
enable creating CSR, ELL and SELLC using the from_ijv interface
jalvesz Jun 29, 2024
dd4dbd8
add example from_ijv
jalvesz Jun 29, 2024
2d7701e
unused matrix
jalvesz Jun 29, 2024
98a564b
add example and spec for add/at
jalvesz Jun 29, 2024
b65d933
example print index
jalvesz Jun 29, 2024
a94272e
add csr2dense direct conversion
jalvesz Jun 29, 2024
e4c1f58
Merge branch 'fortran-lang:master' into sparse
jalvesz Jun 30, 2024
14e2c17
Merge branch 'fortran-lang:master' into sparse
jalvesz Jul 1, 2024
b53eca2
Update doc/specs/stdlib_sparse.md
jalvesz Jul 9, 2024
65e3fcb
Update doc/specs/stdlib_sparse.md
jalvesz Jul 9, 2024
2f56cd4
Update doc/specs/stdlib_sparse.md
jalvesz Jul 9, 2024
941de3a
Update doc/specs/stdlib_sparse.md
jalvesz Jul 9, 2024
575c426
Update doc/specs/stdlib_sparse.md
jalvesz Jul 9, 2024
db73fdc
Update src/stdlib_sparse_kinds.fypp
jalvesz Jul 9, 2024
697afa2
Update src/stdlib_sparse_kinds.fypp
jalvesz Jul 9, 2024
c97e665
Update src/stdlib_sparse_kinds.fypp
jalvesz Jul 9, 2024
ac100a1
Merge branch 'fortran-lang:master' into sparse
jalvesz Jul 9, 2024
9879a9c
Merge branch 'fortran-lang:master' into sparse
jalvesz Jul 9, 2024
dde88a7
refactor spmv as submodule to keep parameters private, rework specs
jalvesz Jul 10, 2024
6ae038b
add an ilp parameter to change in the future for int64 if needed for …
jalvesz Jul 10, 2024
3596f3f
add the _type suffix to all sparse types
jalvesz Jul 12, 2024
a21d1e8
Merge branch 'fortran-lang:master' into sparse
jalvesz Jul 13, 2024
c8d94a3
rollback on submodules
jalvesz Jul 31, 2024
82dbe02
forgotten file in cmake
jalvesz Jul 31, 2024
a8aa247
Merge branch 'fortran-lang:master' into sparse
jalvesz Aug 19, 2024
66b0ce2
Merge branch 'fortran-lang:master' into sparse
jalvesz Aug 21, 2024
4b41aa1
Merge branch 'fortran-lang:master' into sparse
jalvesz Sep 15, 2024
ab112e6
Merge branch 'fortran-lang:master' into sparse
jalvesz Sep 18, 2024
bc0021b
add csc/coo conversions and diagonal extraction
jalvesz Sep 20, 2024
7279461
Merge branch 'fortran-lang:master' into sparse
jalvesz Sep 24, 2024
a4d9306
Add in place operator for coo and csr spmv
jalvesz Oct 19, 2024
cd30636
add support for op with ellpack
jalvesz Oct 19, 2024
b68b4c8
add support for op with csc format
jalvesz Oct 19, 2024
62c702b
unit test in-place transpose
jalvesz Oct 19, 2024
581d215
Merge branch 'fortran-lang:master' into sparse
jalvesz Oct 19, 2024
59d33f0
complete spmv for the ellpack format including symmetric representations
jalvesz Oct 19, 2024
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
243 changes: 243 additions & 0 deletions doc/specs/stdlib_sparse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
---
title: sparse
---

# The `stdlib_sparse` module

[TOC]

## Introduction

The `stdlib_sparse` module provides several derived types defining known sparse matrix data structures. It also provides basic sparse kernels such as sparse matrix vector and conversion between matrix types.
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

## Derived types provided
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### The `sparse_type` abstract derived type
#### Status

Experimental

#### Description
The `sparse_type` is defined as an abstract derived type holding the basic common meta data needed to define a sparse matrix. All other sparse types falvors are derived from the `sparse_type`.
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

```Fortran
type, public, abstract :: sparse_type
integer :: nrows !> number of rows
jalvesz marked this conversation as resolved.
Show resolved Hide resolved
integer :: ncols !> number of columns
integer :: nnz !> number of non-zero values
integer :: storage !> assumed storage symmetry
integer :: base !> index base = 0 for (C) or 1 (Fortran)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the option to use either C or Fortran indexing. My only concern is: what is the advantage of hard-coding it into the data structure? Shouldn't the internal representation be unique (e.g., 1-based)? My fear is that handling two options for the internal representation would be too complicate when more complex functions are implemented. Instead, wouldn't it be better to add this option only to the set/get interfaces. For example:

! Get matrix value at (i,j) == (1,4)
val = matrix%at(0, 3, zero_based=.true.)

! Set matrix row from data and 1-based column indices
call matrix%set_row(row=i, data = [1,2,3,4,5], columns=[3,8,35,1,3], zero_based=.false.)

end type
jvdp1 marked this conversation as resolved.
Show resolved Hide resolved
```

The storage integer label should be assigned from the module's internal enumerator containing the following three enums:

```Fortran
enum, bind(C)
enumerator :: sparse_full !> Full Sparse matrix (no symmetry considerations)
enumerator :: sparse_lower !> Symmetric Sparse matrix with triangular inferior storage
enumerator :: sparse_upper !> Symmetric Sparse matrix with triangular supperior storage
end enum
```
In the following, all sparse kinds will be presented in two main flavors: a data-less type `<matrix>_type` useful for topological graph operations. And real/complex valued types `<matrix>_<kind>` containing the `data` buffer for the matrix values. The following rectangular matrix will be used to showcase how each sparse matrix holds the data internally:
perazz marked this conversation as resolved.
Show resolved Hide resolved

$$ M = \begin{bmatrix}
9 & 0 & 0 & 0 & -3 \\
4 & 7 & 0 & 0 & 0 \\
0 & 8 & -1 & 8 & 0 \\
4 & 0 & 5 & 6 & 0 \\
\end{bmatrix} $$
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `COO`: The COOrdinates compressed sparse format
#### Status

Experimental

#### Description
The `COO`, triplet or `ijv` format defines all non-zero elements of the matrix by explicitly allocating the `i,j` index and the value of the matrix. While some implementations use separate `row` and `col` arrays for the index, here we use a 2D array in order to promote fast memory acces to `ij`.

```Fortran
type(COO_sp) :: COO
call COO%malloc(4,5,10)
perazz marked this conversation as resolved.
Show resolved Hide resolved
COO%data(:) = real([9,-3,4,7,8,-1,8,4,5,6])
COO%index(1:2,1) = [1,1]
COO%index(1:2,2) = [1,5]
COO%index(1:2,3) = [2,1]
COO%index(1:2,4) = [2,2]
COO%index(1:2,5) = [3,2]
COO%index(1:2,6) = [3,3]
COO%index(1:2,7) = [3,4]
COO%index(1:2,8) = [4,1]
COO%index(1:2,9) = [4,3]
COO%index(1:2,10) = [4,4]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `CSR`: The Compressed Sparse Row or Yale format
#### Status

Experimental

#### Description
The Compressed Sparse Row or Yale format `CSR` stores the matrix index by compressing the row indeces with a counter pointer `rowptr` enabling to know the first and last non-zero colum index `col` of the given row.
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

```Fortran
type(CSR_sp) :: CSR
call CSR%malloc(4,5,10)
CSR%data(:) = real([9,-3,4,7,8,-1,8,4,5,6])
CSR%col(:) = [1,5,1,2,2,3,4,1,3,4]
CSR%rowptr(:) = [1,3,5,8,11]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `CSC`: The Compressed Sparse Column format
#### Status

Experimental

#### Description
The Compressed Sparse Colum `CSC` is similar to the `CSR` format but values are accesed first by colum, thus an index counter is given by `colptr` which enables accessing the start and ending rows of a given colum in the `row` index table.
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

```Fortran
type(CSC_sp) :: CSC
call CSC%malloc(4,5,10)
CSC%data(:) = real([9,4,4,7,8,-1,5,8,6,-3])
CSC%row(:) = [1,2,4,2,3,3,4,3,4,1]
CSC%colptr(:) = [1,4,6,8,10,11]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `ELLPACK`: ELL-pack storage format
#### Status

Experimental

#### Description
The `ELL` format stores the data in a dense matrix of $nrows \times K$ in column major order. By imposing a constant number of zeros per row $K$, this format will incure in additional zeros being stored, but it enables efficient vectorization as memory acces are carried out by constant sized strides.
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

```Fortran
type(ELL_sp) :: ELL
call ELL%malloc(num_rows=4,num_cols=5,num_nz_row=3)
ELL%data(1,1:3) = real([9,-3,0])
ELL%data(2,1:3) = real([4,7,0])
ELL%data(3,1:3) = real([8,-1,8])
ELL%data(4,1:3) = real([4,5,6])

ELL%index(1,1:3) = [1,5,0]
ELL%index(2,1:3) = [1,2,0]
ELL%index(3,1:3) = [2,3,4]
ELL%index(4,1:3) = [1,3,4]
```
<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
### `SELL-C`: The Sliced ELLPACK with Constant blocks format
#### Status

Experimental

#### Description
The Sliced ELLPACK format `SELLC` is a variation of the `ELLPACK` format. This modification reduces the storage size compared to the `ELLPACK` format but maintaining its efficient data access scheme. It can be seen as an intermediate format between `CSR` and `ELLPACK`. For more details read [here](https://arxiv.org/pdf/1307.6209v1)
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
## `spmv` - Sparse Matrix-Vector product

### Status

Experimental

### Description

Provide sparse matrix-vector product kernels for the current supported sparse matrix types.

$$y=\alpha*M*x+\beta*y$$

### Syntax

`call ` [[stdlib_sparse_spmv(module):spmv(interface)]] `(matrix,vec_x,vec_y [,alpha,beta])`

### Arguments

`matrix`, `intent(in)`: Shall be a `real` or `complex` sparse type matrix.

`vec_x`, `intent(in)`: Shall be a rank-1 or rank-2 array of `real` or `complex` type array.

`vec_y`, `intent(inout)`: Shall be a rank-1 or rank-2 array of `real` or `complex` type array.

`alpha`, `intent(in)`, `optional` : Shall be a scalar value of the same type as `vec_x`. Default value `alpha=1`.

`beta`, `intent(in)`, `optional` : Shall be a scalar value of the same type as `vec_x`. Default value `beta=0`.

<!-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -->
## `sparse_conversion` - Sparse matrix to matrix conversions

### Status

Experimental

### Description

This module provides facility functions for converting between storage formats.
jvdp1 marked this conversation as resolved.
Show resolved Hide resolved

### Syntax

`call ` [[stdlib_sparse_conversion(module):coo2ordered(interface)]] `(coo)`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like having subroutines to maximize performance and avoid the issues with function assignment. I wonder if we should also provide 'clean' function interfaces to generate new objects? Just giving it a thought.

They would probably pair better with overloaded operators for example, but also in other ways. For example, one could have:

type(COO_sp) :: mat
[...]

! Convert to CSR using interface CSR_sp and then do stuff
call my_CSR_kernel( CSR_sp(mat) , x , y, z )

This would require to add an interface

interface CSR_sp
   module procedure coo2csr_fun
end interface

elemental type(CSR_sp) function coo2csr_fun(COO) result(CSR)
    type(COO_sp), intent(in) :: COO
    call coo2csr( COO, CSR )
end function


### Arguments

`COO`, `intent(inout)`: Shall be any `COO` type. The same object will be returned with the arrays reallocated to the correct size after removing duplicates.

`sort_data`, `logical(in)`, `optional`:: Boolean optional to determine whether to sort the data in the COO graph while sorting the index array, defult `.false.`.
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

### Syntax

`call ` [[stdlib_sparse_conversion(module):dense2coo(interface)]] `(dense,coo)`

### Arguments

`dense`, `intent(in)`: Shall be a rank-2 array of `real` or `complex` type.

`coo`, `intent(inout)`: Shall be a `COO` type of `real` or `complex` type.
jalvesz marked this conversation as resolved.
Show resolved Hide resolved

### Syntax

`call ` [[stdlib_sparse_conversion(module):coo2dense(interface)]] `(coo,dense)`

### Arguments

`coo`, `intent(in)`: Shall be a `COO` type of `real` or `complex` type.

`dense`, `intent(inout)`: Shall be a rank-2 array of `real` or `complex` type.

### Syntax

`call ` [[stdlib_sparse_conversion(module):coo2csr(interface)]] `(coo,csr)`

### Arguments

`coo`, `intent(in)`: Shall be a `COO` type of `real` or `complex` type.

`csr`, `intent(inout)`: Shall be a `CSR` type of `real` or `complex` type.

### Syntax

`call ` [[stdlib_sparse_conversion(module):csr2coo(interface)]] `(csr,coo)`

### Arguments

`csr`, `intent(in)`: Shall be a `CSR` type of `real` or `complex` type.

`coo`, `intent(inout)`: Shall be a `COO` type of `real` or `complex` type.

### Syntax

`call ` [[stdlib_sparse_conversion(module):csr2sellc(interface)]] `(csr,sellc[,chunk])`

### Arguments

`csr`, `intent(in)`: Shall be a `CSR` type of `real` or `complex` type.

`sellc`, `intent(inout)`: Shall be a `SELLC` type of `real` or `complex` type.

`chunk`, `intent(in)`, `optional`: chunk size for the Sliced ELLPACK format.

## Example
```fortran
{!example/linalg/example_sparse_spmv.f90!}
```
1 change: 1 addition & 0 deletions example/linalg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ ADD_EXAMPLE(lstsq2)
ADD_EXAMPLE(solve1)
ADD_EXAMPLE(solve2)
ADD_EXAMPLE(solve3)
ADD_EXAMPLE(sparse_spmv)
ADD_EXAMPLE(svd)
ADD_EXAMPLE(svdvals)
ADD_EXAMPLE(determinant)
Expand Down
36 changes: 36 additions & 0 deletions example/linalg/example_sparse_spmv.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
program example_sparse_spmv
use stdlib_linalg_constants, only: dp
use stdlib_sparse
implicit none

integer, parameter :: m = 4, n = 2
real(dp) :: A(m,n), x(n)
real(dp) :: y_dense(m), y_coo(m), y_csr(m)
real(dp) :: alpha, beta
type(COO_dp) :: COO
type(CSR_dp) :: CSR

call random_number(A)
! Convert from dense to COO and CSR matrices
call dense2coo( A , COO )
call coo2csr( COO , CSR )

! Initialize vectors
x = 1._dp
y_dense = 2._dp
y_coo = y_dense
y_csr = y_dense

! Perform matrix-vector product
alpha = 3._dp; beta = 2._dp
y_dense = alpha * matmul(A,x) + beta * y_dense
call spmv( COO , x , y_coo , alpha = alpha, beta = beta )
call spmv( CSR , x , y_csr , alpha = alpha, beta = beta )

print *, 'dense :', y_dense
print *, 'coo :', y_coo
print *, 'csr :', y_csr

end program example_sparse_spmv


5 changes: 5 additions & 0 deletions include/common.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

#! Real types to be considered during templating
#:set REAL_TYPES = ["real({})".format(k) for k in REAL_KINDS]
#:set REAL_SUFFIX = REAL_KINDS

#! Collected (kind, type) tuples for real types
#:set REAL_KINDS_TYPES = list(zip(REAL_KINDS, REAL_TYPES, REAL_INIT))
Expand All @@ -62,6 +63,7 @@

#! Complex types to be considered during templating
#:set CMPLX_TYPES = ["complex({})".format(k) for k in CMPLX_KINDS]
#:set CMPLX_SUFFIX = ["c{}".format(k) for k in CMPLX_KINDS]

#! Collected (kind, type, initial) tuples for complex types
#:set CMPLX_KINDS_TYPES = list(zip(CMPLX_KINDS, CMPLX_TYPES, CMPLX_INIT))
Expand Down Expand Up @@ -102,6 +104,9 @@
#! Bitset types to be considered during templating
#:set BITSET_TYPES = ["type({})".format(k) for k in BITSET_KINDS]

#! Sparse types to be considered during templating
#:set SPARSE_KINDS = ["COO", "CSR", "CSC", "ELL"]

#! Whether Fortran 90 compatible code should be generated
#:set VERSION90 = defined('VERSION90')

Expand Down
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ set(fppFiles
stdlib_sorting_ord_sort.fypp
stdlib_sorting_sort.fypp
stdlib_sorting_sort_index.fypp
stdlib_sparse_conversion.fypp
stdlib_sparse_kinds.fypp
stdlib_sparse_spmv.fypp
stdlib_specialfunctions_gamma.fypp
stdlib_stats.fypp
stdlib_stats_corr.fypp
Expand Down Expand Up @@ -109,6 +112,7 @@ set(SRC
stdlib_logger.f90
stdlib_sorting_radix_sort.f90
stdlib_system.F90
stdlib_sparse.f90
stdlib_specialfunctions.f90
stdlib_specialfunctions_legendre.f90
stdlib_quadrature_gauss.f90
Expand Down
6 changes: 6 additions & 0 deletions src/stdlib_sparse.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
!! public API
module stdlib_sparse
use stdlib_sparse_kinds
use stdlib_sparse_spmv
use stdlib_sparse_conversion
end module stdlib_sparse
Loading
Loading