Skip to content

Replace Small Array Allocation with StaticArrays#5

Merged
DhairyaLGandhi merged 13 commits into
mainfrom
dg/static
Dec 23, 2025
Merged

Replace Small Array Allocation with StaticArrays#5
DhairyaLGandhi merged 13 commits into
mainfrom
dg/static

Conversation

@DhairyaLGandhi

Copy link
Copy Markdown
Collaborator

No description provided.

Comment thread src/hvncat_static_opt.jl Outdated
Comment on lines +41 to +42
operation(::AbstractArray) = SymbolicUtils.Code.create_array
arguments(x::AbstractArray) = [SymbolicUtils.Code.create_array, size(x), x]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's type piracy

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Additionally, the arguments implementation is incorrect even if this wasn't type piracy. Why do the arguments also contain create_array if the operation is supposedly create_array? create_array takes the following arguments:

  • the array type
  • the eltype (or nothing)
  • Val(ndims)
  • Val(size)
  • the elements of the array (splatted)

Assuming we always use the "full" signature. The shorter signature doesn't have ndims, but it's valid to just ignore that.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Yeah... the thing is that arguments behaves very weirdly and seems to splat the fields of a struct at various times. Not sure if that is expected. This is me trying to work around that behaviour and forward the case we hit an array to the same path as create_array which does actually work.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

well this is now faithful to what arguments shuold have returned now, but the implementation seems to be buried deep within TermInterface which seems like it wants to do a generic implementation. Can this definition just be slotted in

Comment thread src/hvncat_static_opt.jl Outdated
Dispatches on operation type for type-safe extraction.
"""
get_dims_arg(::typeof(SymbolicUtils.array_literal), args) = args[1]
get_dims_arg(::typeof(SymbolicUtils.Code.create_array), args) = args[2]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would also need to change to args[4] with the correct arguments definition.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yeah, this is done now

Comment thread src/hvncat_static_opt.jl
if issym(var)
for p in expr.pairs
if lhs(p) === var
return iscall(p) ? nothing : rhs(p)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Isn't p either an Assignment or DestructuredArgs? Would these ever return true from iscall?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, isn't this function essentially identical to resolve_dims_argument?

Comment thread src/hvncat_static_opt.jl Outdated
end

function infer_hvncat_dimensions(::typeof(SymbolicUtils.Code.create_array), args, expr::Code.Let)
args[2]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The dims are the 4th argument to create_array

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done

Comment thread src/hvncat_static_opt.jl Outdated
Limit to 4×4 (16 elements) for optimal performance.
"""
function is_small_hvncat(rows::Int, cols::Int)
return rows <= 4 && cols <= 4 && rows * cols <= 16

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why not just rows * cols <= 16?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Could do.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is done as well

Comment thread src/hvncat_static_opt.jl Outdated
dims === nothing && continue

# Check if small enough for StaticArrays
# is_small_hvncat(dims[1], dims[2]) || continue

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why is this validation commented?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

There are cases where some of the dims are calculated on the fly or might look like (3,3) but is acttually not the literal tuple but a different type, which fails the check. This is known, and something I am looking at fixing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is enabled now

Comment thread src/hvncat_static_opt.jl Outdated
T = vartype(lhs_var)

# Fallback: use literal dims values for hcat/vcat cases
if length(dims) == 2 && dims[2] == 1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A (3, 1) matrix is not the same as a (3,) vector. They're different types and dispatch differently.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We can simplify this to retain types. This currently comes from us adding a trailing singular dimension in the detection check, and controlling for that by discarding it in favour of a Vector.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This shuold be improved now

@DhairyaLGandhi DhairyaLGandhi merged commit da839d7 into main Dec 23, 2025
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants