Skip to content

Commit

Permalink
Merge pull request #578 from gridap/optimizations
Browse files Browse the repository at this point in the history
Misc Optimizations
  • Loading branch information
fverdugo authored Apr 12, 2021
2 parents 22044c8 + d7223f6 commit 612187d
Show file tree
Hide file tree
Showing 69 changed files with 1,172 additions and 230 deletions.
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.16.0] - Unreleased

### Added
- User API to select specific quadrature rules.
- Experimental support for mixed dimensional PDEs. Since PR [#567](https://github.com/gridap/Gridap.jl/pull/567).

### Changed
- The default quadrature rule for tets has changed.
- Refactoring in `SparseMatrixAssembler` to make it more extensible and efficient. Since PR [#568](https://github.com/gridap/Gridap.jl/pull/568).
- Renamed `get_free_values` -> `get_free_dof_values`. Since PR [#567](https://github.com/gridap/Gridap.jl/pull/567).
- Miscellaneous changes in the FE assembly to allow the solution of mixed dimensional problems. Since PR [#567](https://github.com/gridap/Gridap.jl/pull/567).

### Removed
- Module `Gridap.Integration` has been deleted and its contents have been merged into `Gridap.ReferenceFEs` module.
- Types `SparseMatrixCSR` and `SymSparseMatrixCSR` have been moved to the registered package [`SparseMatricesCSR`](https://github.com/gridap/SparseMatricesCSR.jl). To use them simply add `SparseMatricesCSR` into your environment and type `using SparseMatricesCSR`. Since Since PR [#568](https://github.com/gridap/Gridap.jl/pull/568).

## [0.15.4] - 2021-03-29

### Fixed
- Bug in `CartesianDiscreteModel` with periodic boundary conditions that shows up in Julia 1.6 but not in Julia 1.5. Since commit [da005cf](https://github.com/gridap/Gridap.jl/commit/da005cf4cde68617f92d76744e307798ef7e8340).

## [0.15.3] - 2021-03-16

### Added
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ JSON = "0.21.0"
LineSearches = "7.0.1"
NLsolve = "4.3.0"
QuadGK = "2.3.1, 2.4"
StaticArrays = "0.12.1, 1.0"
SparseMatricesCSR = "0.6"
StaticArrays = "0.12.1, 1.0"
WriteVTK = "1.7, 1.8"
julia = "1.3"

Expand Down
1 change: 0 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ pages = [
"Gridap.TensorValues" => "TensorValues.md",
"Gridap.Fields" => "Fields.md",
"Gridap.Polynomials" => "Polynomials.md",
"Gridap.Integration" => "Integration.md",
"Gridap.ReferenceFEs" => "ReferenceFEs.md",
"Gridap.Geometry" => "Geometry.md",
"Gridap.CellData" => "CellData.md",
Expand Down
10 changes: 0 additions & 10 deletions docs/src/Integration.md

This file was deleted.

2 changes: 2 additions & 0 deletions src/Algebra/Algebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import Base: convert, size, getindex, show, count, *
import LinearAlgebra: mul!
import SparseArrays: nnz, nonzeros, nzrange, findnz, rowvals

export length_to_ptrs!
export rewind_ptrs!
export allocate_vector
export allocate_matrix
export allocate_matrix_and_vector
Expand Down
24 changes: 24 additions & 0 deletions src/Algebra/AlgebraInterfaces.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@

"""
rewind_ptrs!(ptrs)
Rewind the given vector of pointers.
"""
function rewind_ptrs!(ptrs::AbstractVector{<:Integer})
@inbounds for i in (length(ptrs)-1):-1:1
ptrs[i+1] = ptrs[i]
end
ptrs[1] = 1
end

"""
length_to_ptrs!(ptrs)
Given a vector of integers, mutate it from length state to pointer state.
"""
function length_to_ptrs!(ptrs::AbstractArray{<:Integer})
ptrs[1] = 1
@inbounds for i in 1:(length(ptrs)-1)
ptrs[i+1] += ptrs[i]
end
end

function allocate_matrix end
function allocate_matrix_and_vector end

Expand Down
213 changes: 213 additions & 0 deletions src/Algebra/SparseMatrixCSC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,216 @@ end
push!(V,v)
nothing
end

#@inline function add_entries!(
# combine::Function,
# A::SparseMatrixCSC,
# vs::AbstractMatrix{<:Number},
# is,js)
#
# if issorted(is)
# nz = A.nzval
# ptrs = A.colptr
# rows = A.rowval
# for (lj,j) in enumerate(js)
# if j>0
# pini = ptrs[j]
# pend = ptrs[j+1]-1
# li = 1
# for p in pini:pend
# _i = rows[p]
# if _i == is[li]
# vij = vs[li,lj]
# Aij = nz[p]
# nz[p] = combine(Aij,vij)
# li += 1
# end
# end
# end
# end
# else
# for (lj,j) in enumerate(js)
# if j>0
# for (li,i) in enumerate(is)
# if i>0
# vij = vs[li,lj]
# add_entry!(combine,A,vij,i,j)
# end
# end
# end
# end
# end
# A
#end

struct CounterCSRR{Tv,Ti}
tv::Type{Tv}
nrows::Int
ncols::Int
rowptrs::Vector{Ti}
end

LoopStyle(::Type{<:CounterCSRR}) = Loop()

@inline function add_entry!(::typeof(+),a::CounterCSRR{Tv,Ti},v,i,j) where {Tv,Ti}
a.rowptrs[i+1] += Ti(1)
nothing
end

struct CSRR{Tv,Ti}
nrows::Int
ncols::Int
rowptrs::Vector{Ti}
colvals::Vector{Ti}
nzvals::Vector{Tv}
end

LoopStyle(::Type{<:CSRR}) = Loop()

@inline function add_entry!(::typeof(+),a::CSRR{Tv,Ti},v::Nothing,i,j) where {Tv,Ti}
p = a.rowptrs[i]
a.colvals[p] = j
a.rowptrs[i] = p+Ti(1)
nothing
end

@inline function add_entry!(::typeof(+),a::CSRR{Tv,Ti},v,i,j) where {Tv,Ti}
p = a.rowptrs[i]
a.colvals[p] = j
a.nzvals[p] = v
a.rowptrs[i] = p+Ti(1)
nothing
end

function nz_counter(::Type{SparseMatrixCSC{Tv,Ti}},axes) where {Tv,Ti}
nrows = length(axes[1])
ncols = length(axes[2])
rowptrs = zeros(Ti,nrows+1)
CounterCSRR(Tv,nrows,ncols,rowptrs)
end

function nz_allocation(a::CounterCSRR{Tv,Ti}) where {Tv,Ti}
rowptrs = a.rowptrs
length_to_ptrs!(rowptrs)
ndata = rowptrs[end]-1
colvals = zeros(Ti,ndata)
nzvals = zeros(Tv,ndata)
CSRR(a.nrows,a.ncols,rowptrs,colvals,nzvals)
end

function create_from_nz(a::CSRR{Tv,Ti}) where {Tv,Ti}
rewind_ptrs!(a.rowptrs)
A = _csrr_to_csc!(a)
A
end

function _csrr_to_csc!(csrr::CSRR{Tv,Ti}) where {Tv,Ti}
nrows = csrr.nrows
ncols = csrr.ncols
rowptrs = csrr.rowptrs
colvals = csrr.colvals
nzvalscsr = csrr.nzvals

@assert nrows == length(rowptrs)-1
colptrs = Vector{Ti}(undef,ncols+1)
work = Vector{Ti}(undef,ncols)
cscnnz = _csrr_to_csc_count!(colptrs,rowptrs,colvals,nzvalscsr,work)
rowvals = Vector{Ti}(undef,cscnnz)
nzvalscsc = Vector{Tv}(undef,cscnnz)
_csrr_to_csc_fill!(colptrs,rowvals,nzvalscsc,rowptrs,colvals,nzvalscsr)
SparseMatrixCSC(nrows,ncols,colptrs,rowvals,nzvalscsc)
end

# Notation
# csrr: csr with repeated and unsorted columns
# csru: csr witu unsorted columns
# csc: csc with sorted columns

# Adapted form SparseArrays
function _csrr_to_csc_count!(
colptrs::Vector{Ti},
rowptrs::Vector{Tj},
colvals::Vector{Tj},
nzvalscsr::Vector{Tv},
work::Vector{Tj}) where {Ti,Tj,Tv}

nrows = length(rowptrs)-1
ncols = length(colptrs)-1
if nrows == 0 || ncols == 0
fill!(colptrs, Ti(1))
return Tj(0)
end

# Convert csrr to csru by identifying repeated cols with array work.
# At the same time, count number of unique rows in colptrs shifted by one.
fill!(colptrs, Ti(0))
fill!(work, Tj(0))
writek = Tj(1)
newcsrrowptri = Ti(1)
origcsrrowptri = Tj(1)
origcsrrowptrip1 = rowptrs[2]
@inbounds for i in 1:nrows
for readk in origcsrrowptri:(origcsrrowptrip1-Tj(1))
j = colvals[readk]
if work[j] < newcsrrowptri
work[j] = writek
if writek != readk
colvals[writek] = j
nzvalscsr[writek] = nzvalscsr[readk]
end
writek += Tj(1)
colptrs[j+1] += Ti(1)
else
klt = work[j]
nzvalscsr[klt] = +(nzvalscsr[klt], nzvalscsr[readk])
end
end
newcsrrowptri = writek
origcsrrowptri = origcsrrowptrip1
origcsrrowptrip1 != writek && (rowptrs[i+1] = writek)
i < nrows && (origcsrrowptrip1 = rowptrs[i+2])
end

# Convert colptrs from counts to ptrs shifted by one
# (ptrs will be corrected below)
countsum = Tj(1)
colptrs[1] = Ti(1)
@inbounds for j in 2:(ncols+1)
overwritten = colptrs[j]
colptrs[j] = countsum
countsum += overwritten
@check Base.hastypemax(Ti) && (countsum <= typemax(Ti))
end

cscnnz = countsum - Tj(1)
cscnnz
end

function _csrr_to_csc_fill!(
colptrs::Vector{Ti},rowvals::Vector{Ti},nzvalscsc::Vector{Tv},
rowptrs::Vector{Tj},colvals::Vector{Tj},nzvalscsr::Vector{Tv}) where {Ti,Tj,Tv}

nrows = length(rowptrs)-1
ncols = length(colptrs)-1
if nrows == 0 || ncols == 0
return nothing
end

# From csru to csc
# Tracking write positions in colptrs corrects
# the column pointers to the final value.
@inbounds for i in 1:nrows
for csrk in rowptrs[i]:(rowptrs[i+1]-Tj(1))
j = colvals[csrk]
x = nzvalscsr[csrk]
csck = colptrs[j+1]
colptrs[j+1] = csck + Ti(1)
rowvals[csck] = i
nzvalscsc[csck] = x
end
end

nothing
end


Loading

0 comments on commit 612187d

Please sign in to comment.