Skip to content

Commit d20c5f0

Browse files
authored
Merge pull request #162 from Cthonios/chchchchanges
block arrays ext, initial stab at matrix free assembler and adding ex…
2 parents 3fd6c38 + 0ac25be commit d20c5f0

File tree

7 files changed

+117
-74
lines changed

7 files changed

+117
-74
lines changed

Project.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@ TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
1818
[weakdeps]
1919
AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
2020
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
21+
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
2122
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
2223
Exodus = "f57ae99e-f805-4780-bdca-96e224be1e5a"
2324

2425
[extensions]
2526
FiniteElementContainersAMDGPUExt = ["Adapt", "AMDGPU"]
2627
FiniteElementContainersAdaptExt = "Adapt"
28+
FiniteElementContainersBlockArraysExt = "BlockArrays"
2729
FiniteElementContainersCUDAExt = ["Adapt", "CUDA"]
2830
FiniteElementContainersExodusExt = "Exodus"
2931

@@ -32,6 +34,7 @@ AMDGPU = "2"
3234
Adapt = "4"
3335
Aqua = "0.8"
3436
Atomix = "1"
37+
BlockArrays = "1"
3538
CUDA = "5"
3639
DocStringExtensions = "0.9"
3740
Exodus = "0.14"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module FiniteElementContainersBlockArraysExt
2+
3+
using BlockArrays
4+
using FiniteElementContainers
5+
6+
function FiniteElementContainers.create_unknowns(assemblers::NamedTuple)
7+
Uus = map(create_unknowns, collect(values(assemblers)))
8+
return mortar(Uus)
9+
end
10+
11+
end # module

src/DofManagers.jl

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,36 @@ function create_unknowns(dof::DofManager)
6262
return KA.zeros(backend, Float64, length(dof.unknown_dofs))
6363
end
6464

65+
# COV_EXCL_START
66+
KA.@kernel function _extract_field_unknowns_kernel!(Uu::V, dof::DofManager, U::AbstractField) where V <: AbstractVector{<:Number}
67+
N = KA.@index(Global)
68+
@inbounds Uu[N] = U[dof.unknown_dofs[N]]
69+
end
70+
# COV_EXCL_STOP
71+
72+
function _extract_field_unknowns!(Uu::V, dof::DofManager, U::AbstractField, backend::KA.Backend) where V <: AbstractVector{<:Number}
73+
kernel! = _extract_field_unknowns_kernel!(backend)
74+
kernel!(Uu, dof, U, ndrange = length(Uu))
75+
return nothing
76+
end
77+
78+
function _extract_field_unknowns!(Uu::V, dof::DofManager, U::AbstractField, ::KA.CPU) where V <: AbstractVector{<:Number}
79+
@views Uu .= U[dof.unknown_dofs]
80+
return nothing
81+
end
82+
83+
function extract_field_unknowns!(
84+
Uu::V,
85+
dof::DofManager,
86+
U::AbstractField
87+
) where V <: AbstractVector{<:Number}
88+
backend = KA.get_backend(dof)
89+
@assert KA.get_backend(U) == backend
90+
@assert KA.get_backend(Uu) == backend
91+
_extract_field_unknowns!(Uu, dof, U, backend)
92+
return nothing
93+
end
94+
6595
function function_space(dof::DofManager)
6696
return dof.var.fspace
6797
end
@@ -84,20 +114,20 @@ function update_dofs!(dof::DofManager, dirichlet_dofs)
84114
end
85115

86116
# COV_EXCL_START
87-
KA.@kernel function _update_field_unknowns_kernel!(U::H1Field, dof::DofManager, Uu::T) where T <: AbstractArray{<:Number, 1}
117+
KA.@kernel function _update_field_unknowns_kernel!(U::AbstractField, dof::DofManager, Uu::V) where V <: AbstractVector{<:Number}
88118
N = KA.@index(Global)
89119
@inbounds U[dof.unknown_dofs[N]] = Uu[N]
90120
end
91121
# COV_EXCL_STOP
92122

93-
function _update_field_unknowns!(U::H1Field, dof::DofManager, Uu::T, backend::KA.Backend) where T <: AbstractArray{<:Number, 1}
123+
function _update_field_unknowns!(U::AbstractField, dof::DofManager, Uu::T, backend::KA.Backend) where T <: AbstractVector{<:Number}
94124
kernel! = _update_field_unknowns_kernel!(backend)
95125
kernel!(U, dof, Uu, ndrange = length(Uu))
96126
return nothing
97127
end
98128

99129
# Need a seperate CPU method since CPU is basically busted in KA
100-
function _update_field_unknowns!(U::H1Field, dof::DofManager, Uu::T, ::KA.CPU) where T <: AbstractArray{<:Number, 1}
130+
function _update_field_unknowns!(U::AbstractField, dof::DofManager, Uu::T, ::KA.CPU) where T <: AbstractVector{<:Number}
101131
U[dof.unknown_dofs] .= Uu
102132
return nothing
103133
end

src/assemblers/Assemblers.jl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,12 @@ end
172172
$(TYPEDSIGNATURES)
173173
"""
174174
function hvp(assembler::AbstractAssembler)
175-
return _hvp(assembler, KA.get_backend(assembler))
175+
extract_field_unknowns!(
176+
asm.stiffness_action_unknowns,
177+
asm.dof,
178+
asm.stiffness_action_storage
179+
)
180+
return nothing
176181
end
177182

178183
"""
@@ -186,7 +191,12 @@ end
186191
$(TYPEDSIGNATURES)
187192
"""
188193
function residual(asm::AbstractAssembler)
189-
return _residual(asm, KA.get_backend(asm))
194+
extract_field_unknowns!(
195+
asm.residual_unknowns,
196+
asm.dof,
197+
asm.residual_storage
198+
)
199+
return asm.residual_unknowns
190200
end
191201

192202
"""
@@ -200,6 +210,7 @@ end
200210
include("SparsityPattern.jl")
201211

202212
# types
213+
include("MatrixFreeAssembler.jl")
203214
include("SparseMatrixAssembler.jl")
204215

205216
# methods

src/assemblers/MatrixAction.jl

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,6 @@ function _assemble_block_matrix_action!(
8080
end
8181
end
8282

83-
# TODO hardcoded to H1 fields right now.
84-
"""
85-
$(TYPEDSIGNATURES)
86-
"""
87-
function _hvp(asm::AbstractAssembler, ::KA.CPU)
88-
# for n in axes(asm.residual_unknowns, 1)
89-
# asm.residual_unknowns[n] = asm.residual_storage[asm.dof.H1_unknown_dofs[n]]
90-
# end
91-
@views asm.stiffness_action_unknowns .= asm.stiffness_action_storage[asm.dof.H1_unknown_dofs]
92-
return asm.stiffness_action_unknowns
93-
end
94-
9583
# GPU implementation
9684

9785
"""
@@ -187,26 +175,3 @@ function _assemble_block_matrix_action!(
187175
)
188176
return nothing
189177
end
190-
191-
# """
192-
# $(TYPEDSIGNATURES)
193-
# """
194-
# KA.@kernel function _extract_residual_unknowns!(Ru, unknown_dofs, R)
195-
# N = KA.@index(Global)
196-
# Ru[N] = R[unknown_dofs[N]]
197-
# end
198-
199-
"""
200-
$(TYPEDSIGNATURES)
201-
TODO note will only work for H1 spaces right now.
202-
TODO move me to Assemblers.jl
203-
"""
204-
function _hvp(asm::AbstractAssembler, backend::KA.Backend)
205-
kernel! = _extract_residual_unknowns!(backend)
206-
kernel!(asm.stiffness_action_unknowns,
207-
asm.dof.H1_unknown_dofs,
208-
asm.stiffness_action_storage,
209-
ndrange=length(asm.dof.H1_unknown_dofs))
210-
KA.synchronize(KA.get_backend(asm))
211-
return asm.stiffness_action_unknowns
212-
end
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
struct MatrixFreeAssembler{
2+
Dof <: DofManager,
3+
Storage1 <: AbstractField,
4+
Storage2 <: AbstractArray{<:Number, 1}
5+
} <: AbstractAssembler{Dof}
6+
dof::Dof
7+
residual_storage::Storage1
8+
residual_unknowns::Storage2
9+
stiffness_action_storage::Storage1
10+
stiffness_action_unknowns::Storage2
11+
end
12+
13+
function MatrixFreeAssembler(dof::DofManager)
14+
15+
residual_storage = create_field(dof)
16+
residual_unknowns = create_unknowns(dof)
17+
stiffness_action_storage = create_field(dof)
18+
stiffness_action_unknowns = create_unknowns(dof)
19+
return MatrixFreeAssembler(
20+
dof,
21+
residual_storage, residual_unknowns,
22+
stiffness_action_storage, stiffness_action_unknowns
23+
)
24+
end
25+
26+
function MatrixFreeAssembler(u::AbstractFunction)
27+
dof = DofManager(u)
28+
return MatrixFreeAssembler(dof)
29+
end
30+
31+
function update_dofs!(assembler::MatrixFreeAssembler, dirichlet_bcs)
32+
# collect dbcs
33+
if length(dirichlet_bcs) > 0
34+
dirichlet_dofs = mapreduce(x -> x.bookkeeping.dofs, vcat, dirichlet_bcs)
35+
dirichlet_dofs = unique(sort(dirichlet_dofs))
36+
else
37+
dirichlet_dofs = Vector{Int}(undef, 0)
38+
end
39+
40+
# update dof manager
41+
update_dofs!(assembler.dof, dirichlet_dofs)
42+
43+
# update cached arrays in assembler
44+
resize!(assembler.residual_unknowns, length(assembler.dof.unknown_dofs))
45+
resize!(assembler.stiffness_action_unknowns, length(assembler.dof.unknown_dofs))
46+
47+
return nothing
48+
end
49+
50+
Base.eltype(asm::MatrixFreeAssembler) = eltype(asm.residual_storage)
51+
Base.size(asm::MatrixFreeAssembler) = (length(asm.residual_unknowns), length(asm.residual_unknowns))
52+
53+
function LinearAlgebra.mul!(y::T, asm::MatrixFreeAssembler, Uu::T, p) where T
54+
assemble!(asm.stiffness_action_storage, hvp, Uu, p)
55+
copyto!(y, hvp(asm))
56+
return nothing
57+
end

src/assemblers/Vector.jl

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,6 @@ function _assemble_block_vector!(
8181
end
8282
end
8383

84-
# TODO hardcoded to H1 fields right now.
85-
"""
86-
$(TYPEDSIGNATURES)
87-
"""
88-
function _residual(asm::AbstractAssembler, ::KA.CPU)\
89-
@views asm.residual_unknowns .= asm.residual_storage[asm.dof.unknown_dofs]
90-
return asm.residual_unknowns
91-
end
92-
9384
# GPU implementation
9485

9586
"""
@@ -184,28 +175,3 @@ function _assemble_block_vector!(
184175
)
185176
return nothing
186177
end
187-
188-
"""
189-
$(TYPEDSIGNATURES)
190-
"""
191-
# COV_EXCL_START
192-
KA.@kernel function _extract_residual_unknowns!(Ru, unknown_dofs, R)
193-
N = KA.@index(Global)
194-
Ru[N] = R[unknown_dofs[N]]
195-
end
196-
# COV_EXCL_STOP
197-
198-
"""
199-
$(TYPEDSIGNATURES)
200-
"""
201-
function _residual(asm::AbstractAssembler, backend::KA.Backend)
202-
kernel! = _extract_residual_unknowns!(backend)
203-
kernel!(
204-
asm.residual_unknowns,
205-
asm.dof.unknown_dofs,
206-
asm.residual_storage,
207-
ndrange=length(asm.dof.unknown_dofs)
208-
)
209-
KA.synchronize(KA.get_backend(asm))
210-
return asm.residual_unknowns
211-
end

0 commit comments

Comments
 (0)