Utilities

Backend

Bramble.BackendType
Backend{VT, MT, EP}()

Compile-time descriptor specifying vector type VT, matrix type MT, and execution policy EP.

Type parameters

  • VT<:DenseVector: Concrete dense vector type (for CPU or GPU).
  • MT<:AbstractMatrix: Concrete matrix type (e.g. SparseMatrixCSC{Float64, Int} or Matrix{Float64}).
  • EP<:ExecutionPolicy: Execution policy (Serial or Parallel).

See also: backend, vector_type, matrix_type, execution_policy.

source
Base.eltypeMethod
eltype(backend::Backend{VT}) -> Type
eltype(::Type{<:Backend{VT}}) -> Type

Return the coordinate and scalar element type of vector type VT configured in backend.

source

Linear algebra

Bramble.MarkedIndicesType
MarkedIndices(mask::BitVector, offset::Int = 0)

Lazily iterates the 1-based positions where mask is set, each shifted by offset (so a leaf's mask, consulted at its offset into a global vector, yields global indices without copying). Walks whole 64-bit words at a time, skipping zero chunks entirely and extracting set bits via trailing_zeros, so the work is proportional to the number of set bits, not to length(mask).

No bounds guard against length(mask) is needed: BitVector guarantees the padding bits of its final chunk are zero, so the walk never yields an index past the mask's own length.

source
Bramble.MarkedIndicesUnionType
MarkedIndicesUnion(masks::NTuple{N,BitVector}) where N

Lazily iterates the 1-based positions where the union of masks is set.

The multi-marker counterpart of MarkedIndices: _combined_mask (space/inner_product.jl) used to materialize the union into a fresh BitVector via copy + .|= before walking it, one heap allocation per call (gpena/Bramble.jl#149). This ORs each mask's 64-bit chunk on the fly instead, so the union is never materialized – still proportional to the number of set bits, still a whole-word skip wherever every mask's chunk is zero, and allocates nothing.

source
Bramble._LastAxisChunksType
_LastAxisChunks(rest::Tuple, ax::AbstractRange, n::Int)

Splits a CartesianIndices into n blocks along its last axis, each block itself a CartesianIndices over the leading axes rest. Indexable and lazy, so the split allocates nothing and Threads.@threads can partition it directly.

Blocks differ in length by at most one slice: the remainder is spread over the first of them rather than left on the last, so no thread receives a double-sized tail.

source
Bramble._band_countMethod
_band_count(len::Int, span::Int, nthreads::Int) -> Int

How many slabs to cut an axis of len points into for a stencil reaching span along it.

Enough for every thread to hold one slab per colour, never so many that a slab falls below span (which is what keeps alternate slabs free of each other's stencil footprints), and always even so the two colours are balanced. Returns 0 when the axis is too short to band at all, leaving the caller on its point-coloured path.

source
Bramble._band_rangeMethod
_band_range(ax::AbstractRange, nbands::Int, b::Int) -> AbstractRange

The b-th of nbands contiguous slabs of ax.

Slabs differ in length by at most one, the remainder spread over the first of them rather than left on the last. b indexes positions within ax, not values, so an axis carrying a stride keeps it.

source
Bramble._cpu_threaded_for!Method
_cpu_threaded_for!(policy::ExecutionPolicy, v::AbstractArray, idxs, f::Function) -> Nothing

Apply f across indices idxs and write the result into v in place.

Dispatches to sequential iteration for Serial or static work partitioning across threads for Parallel.

Arguments

  • policy: Execution policy (Serial or Parallel).
  • v: Destination array mutated in place.
  • idxs: Iterable collection of linear or Cartesian indices.
  • f: Kernel mapping each index idx to the scalar value stored in v[idx].
source
Bramble._cpu_threaded_scatter_for!Method
_cpu_threaded_scatter_for!(policy::ExecutionPolicy, mats::Tuple, idxs, g::Function) -> Nothing

Evaluate tuple-valued kernel g across idxs and scatter results into destination arrays mats.

Dispatches to sequential execution for Serial or static multithreaded execution for Parallel.

Arguments

  • policy: Execution policy (Serial or Parallel).
  • mats: Tuple of destination arrays mutated in place.
  • idxs: Iterable collection of indices.
  • g: Kernel mapping each index to a tuple of values matching length(mats).
source
Bramble._dotMethod
_dot(u::AbstractVector, v::AbstractVector, w::AbstractVector) -> Real

Compute the weighted trilinear dot product

\[\sum_{i=1}^n u_i v_i w_i\]

Accumulates via fused multiply-add operations (muladd) with @simd vectorization.

A same-eltype specialization used to sit alongside this one, skipping the promote_type call and the T(...) conversions on the (dispatch-favoured) assumption that they cost something. Compared by @code_llvm/@code_native with matching element types (gpena/Bramble.jl#71): identical generated code, since promote_type(T, T, T) === T and T(x::T) is an identity conversion the compiler elides. One method now covers both cases.

Arguments

  • u: First vector.
  • v: Second vector.
  • w: Weight vector.

Throws

  • DimensionMismatch: If length(u), length(v), and length(w) do not match.
source
Bramble._dot_maskedMethod
_dot_masked(u::AbstractVector, v::AbstractVector, w::AbstractVector, mask::BitVector) -> Real

Compute the weighted dot product restricted to indices where mask is true:

\[\sum_{i \in \mathrm{supp}(\mathrm{mask})} u_i v_i w_i\]

Walks MarkedIndices(mask), so the work is proportional to the number of set bits rather than to length(mask).

As with _dot, a same-eltype specialization used to sit alongside this one; @code_llvm/@code_native with matching element types (gpena/Bramble.jl#71) showed identical generated code, so one method now covers both cases.

Arguments

  • u: First vector.
  • v: Second vector.
  • w: Weight vector.
  • mask: Boolean selection mask.

Throws

  • DimensionMismatch: If vector or mask lengths do not match.
source
Bramble._last_axis_chunksMethod
_last_axis_chunks(idxs::CartesianIndices{D}, n::Integer) -> _LastAxisChunks{D}

Return idxs split into at most n blocks along its last axis, clamped to the length of that axis so no block is empty.

source
Bramble._serial_for!Method
_serial_for!(v::AbstractArray, idxs, f::Function) -> Nothing

Iterate sequentially over idxs, writing v[idx] = f(idx) in place.

Arguments

  • v: Destination array mutated in place.
  • idxs: Iterable collection of indices.
  • f: Kernel evaluating values at each index.
source
Bramble._threaded_axis_for!Method
_threaded_axis_for!(v::AbstractArray, idxs::CartesianIndices, f::Function) -> Nothing

As _threaded_for!, for a CartesianIndices: each thread takes one block of whole last-axis slices and walks it natively, never converting a linear index.

source
Bramble._threaded_for!Method
_threaded_for!(v::AbstractArray, idxs, f::Function) -> Nothing

Fill v[idx] with f(idx) across threads, statically partitioning idxs.

Kept in an isolated function to prevent Threads.@threads closure boxing allocations on paths that execute serially.

source
Bramble._write_components!Method
_write_components!(mats::Tuple, vals::Tuple, idx) -> Nothing

Recursively unpack and write elements of vals into destination arrays mats at index idx.

Recursion on tuples unrolls at compile time with zero heap allocations.

source

Macros

Bramble.@forwardMacro
@forward T.field functions
@forward T.field (f, g, ...)

Generate delegating method definitions forwarding function calls on type T to x.field.

For each supplied function f, generates an inlined method:

@inline f(x::T, args...; kwargs...) = f(x.field, args...; kwargs...)

Examples

using Bramble: @forward

struct Container
    data::Vector{Float64}
end

@forward Container.data (Base.length, Base.size)

c = Container([1.0, 2.0, 3.0])
length(c) == 3 && size(c) == (3,)

# output
true
source