Loop Vectorization syntax very limiting

I’m using LoopVectorization to speed up some function to great effect. However, I’m finding the syntax it allows to be quite limiting. I’m loping over a sparse matrix like this to gather an energy function. It works great and is fast, but the syntax is very ugly. Moreover, I would like to hold the sparse matrix in some struct and call everything on the containing struct.

The following works:

function getdE(gstate, gadj::SparseMatrixCSC, idx)
    efac = 0f0
    @turbo check_empty = true for ptr in nzrange(gadj, idx)
        efac += -gstate[gadj.rowval[ptr]]*gadj.nzval[ptr]
    end
    return efac
end

But with this I get errors:

@inline conn_range(adj::SparseMatrixCSC, idx) = nzrange(adj, idx)
@inline getweight(adj::SparseMatrixCSC, ptr) = adj.nzval[ptr]
@inline conn_idx(adj::SparseMatrixCSC, ptr) = adj.rowval[ptr]

function getdE(gstate, gadj::SparseMatrixCSC, idx)
    efac = 0f0
    @turbo check_empty = true for ptr in conn_range(gadj, idx)
        weight = getweight(gadj, ptr)
        cidx = conn_idx(gadj, ptr)
        efac += -gstate[cidx]*weight
    end
    return efac
end

Which normally should compile to the same code, I’m getting the warning that check args failed and it uses @inbounds @fastmath as fallback. Am I doing something wrong?

1 Like

If you want to have super fast code you will always have to sacrifice some beauty and readability… In general, what you have to sacrifice is quite small when using Julia, compared to other languages.

This specific problem is because of how LoopVectorization.jl is implemented.
Maybe the replacement will be ready in a year, which won’t have these limitations.

8 Likes

I agree that in general, performant code will be less readable. In this case however, since I just want to inline the functions anyway, I’m basically just creating an alias which normally is completely compiled away. Couldn’t the macro carry out the inlining somehow?

I’ve seen you are working on LoopModels, it looks awesome, and thanks for all the effort.

1 Like

Nothing to do with Loopvectorization, but did you know that you can write x -= a instead of x += -a?

There’s also /= and *=, etc.

I’m aware! The full expression in my code comes from an energy function, where this term has a minus sign, so IMO it’s a bit more readable like this and, moreover, it’s not always the only term that is added (and the others might not have minus signs)

Macros don’t work on that level. Otherwise they wouldn’t be called macros, I think. EDIT: I see this was already explained in a new thread.