Skip to content

Option to invalidate the array_cache for LazyArray #1117

Open
@tam724

Description

@tam724

Would it make sense to have a way to invalidate the cache for indexing a LazyArray? So that essentially this check in getindex!(...)

if index_and_item.index != index

is skipped and the getindex!(...) call always reevaluates the cache entries (even if the same item was indexed before).

As a MWE I would have liked something like this to work on the first getindex!(...) call:

using Gridap

model = CartesianDiscreteModel((0, 1), 10)
V = TestFESpace(model, ReferenceFE(lagrangian, Float64, 1), conformity=:H1)
Ω = Triangulation(model)
dx = Measure(Ω, 4)

α = Ref(1.0) # I would like to change this value and reevaluate the quadrature without having to build the whole lazy expression again.
g(x) = exp(-α[] * x[1])

b(v) = (g * v)dx

v = get_fe_basis(V)
cell_vec_lazy = b(v)[Ω]
cell_vec_cache = Gridap.array_cache(cell_vec_lazy)
getindex!(cell_vec_cache, cell_vec_lazy, 1)[1]

Gridap.assemble_vector(b, V)[1] # this should return the same value as the getindex!(...) before

# now change α
α[] = 2.0
getindex!(cell_vec_cache, cell_vec_lazy, 1)[1] # returns the same value as before (where α still was 1)
getindex!(cell_vec_cache, cell_vec_lazy, 2)[1]; # this is a workaround to invalidate the cache (simply index into another cell)
getindex!(cell_vec_cache, cell_vec_lazy, 1)[1] # now this returns the value where α = 2

The cache invalidation (here by indexing another cell) could be more explicit and skip the reevaluation of the cache entries. For me implementing something along the lines of this was enough (but I only understand the type-structure of the cache to some extent):

invalidate_cache!(::Union{Nothing, Gridap.Arrays.CachedVector, Gridap.Arrays.CachedMatrix}) = nothing
function invalidate_cache!(cache::Tuple{T1}) where T1
    invalidate_cache!(cache[1])
end
function invalidate_cache!(cache::Tuple{T1, T2}) where {T1, T2}
    invalidate_cache!(cache[1])
    invalidate_cache!(cache[2])
end
function invalidate_cache!(cache::Tuple{T1, T2, T3}) where {T1, T2, T3}
    invalidate_cache!(cache[1])
    invalidate_cache!(cache[2])
    invalidate_cache!(cache[3])
end
function invalidate_cache!(cache::Tuple{T, <:Gridap.Arrays.IndexItemPair}) where T
    invalidate_cache!(cache[1])
    cache[2].index = -1
end

Alternatively, getindex!() could have an optional argument always_reevaluate=false that switches off the index check.

My use case I stumbled upon this while I was experimenting with a probably rather uncommon use case for a FE-library. I wanted to assemble a matrix

a(u, v) = ∫( ∫( k(x₁, x₂) * u(x₁) )dx₁ * v(x₂) ) dx₂
However I thought that I could reuse the quadrature rules, basis function definitions and grid-definitions in Gridap.jl.

Using only high-level interfaces, I could implement the following:

k(x1, x2) = exp(-50.0*(x1-x2)^2)

model = CartesianDiscreteModel((0, 1), 10)
V = TestFESpace(model, ReferenceFE(lagrangian, Float64, 1), conformity=:H1)
Ω = Triangulation(model)
dx = Measure(Ω, 4)
K = zeros(num_free_dofs(V), num_free_dofs(V))
u = FEFunction(V, zeros(num_free_dofs(V)))
for i in 1:num_free_dofs(V)
    u.free_values[i] = 1.0
    K[i, :] = Gridap.assemble_vector(
        v -> (
            (y -> sum(((x -> k(y[1], x[1])) * u)dx))
                * v)dx
        , V)
    u.free_values[i] = 0.0
end

However, the inner quadrature always evaluates the full domain whereas only the cells in the support of the basis u[i] should be integrated. For larger N that quickly becomes prohibitively slow.

Leveraging the low-level APIs of Gridap, I found the getindex! to be essentially the function I needed for cellwise evaluation of the quadrature rules, but I have to change the variable of the outer integration without having to rebuild the inner lazy evaluation tree.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions