Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evaluate use of cfunction closures instead of functionwrappers #159

Open
moustachio-belvedere opened this issue Jan 21, 2023 · 4 comments
Open

Comments

@moustachio-belvedere
Copy link
Member

moustachio-belvedere commented Jan 21, 2023

I spent some time investigating today to see if there was a way of getting exactly what we currently do with functionwrappers, but with cfunctions which are part of base Julia, so we would have a backup option as FunctionWrappers is not heavily maintained.

More work is needed but initial results look promising. For full code see this file in RheoBenchAndTest.

As an example, we can convert

function DM1(p::Array{Symbol}, G::Expr)
    unpack_expr = Meta.parse(string(join(string.(p), ","), ",=params"))
    return(
    (@eval ((t, params) -> begin $unpack_expr; $G; end))
    |> FunctionWrapper{Float64, Tuple{Float64,Vector{Float64}}})
end

to

function DM3(p::Array{Symbol}, G::Expr)
    unpack_expr = Meta.parse(string(join(string.(p), ","), ",=params"))
    anonf = @eval ((t, params) -> begin $unpack_expr; $G; end)
    @cfunction(
      $anonf,
      Float64,
      (Float64, Vector{Float64}))
end

Results for cfunction call are consistently better than FunctionWrappers. However, the overhead for FunctionWrappers is probably only per-function-call so the difference is probably negligible when computing on array versions of the moduli.

A potential issue is that their usage is not quite the same hence more investigation is required on more RHEOS-like use cases.

@akabla @alebonfanti

@moustachio-belvedere
Copy link
Member Author

I've added some more investigations to the file linked above in RheoBenchAndTest.

Looks like it is feasible to yield functions with the same interface as functionwrappers so this could be a back up option if ever needed in future. I don't think there's anything to be done now though so I'll close this issue.

@akabla
Copy link
Member

akabla commented Jan 22, 2023

That's really nice, Louis! Not the usual context to use cfunction, but that seems to work very well as a replacement for the function wrappers. Did you see this used somewhere? [edit: in fact, it looks like this is how FunctionWrappers work...]

There are significant performance improvements too on the test script. I added another cfunction wrapper (DM5) that appears to work fine using the standard Rheos calls, and is very fast indeed. No world age problem when created and called from a function.

This is definitely something to explore further. I don't see reasons to use FunctionWrappers if all can be done with base Julia, with a possible performance boost.
Might be good to test how to work with arrays. Should be possible too.

@akabla akabla reopened this Jan 22, 2023
@akabla
Copy link
Member

akabla commented Jan 22, 2023

I briefly tested cfunction on time arrays. Works fine too. Performance is good, although not too different from function wrappers.

@akabla
Copy link
Member

akabla commented Jan 22, 2023

These are code examples that seem to deliver what we need:

function DM5(p::Array{Symbol}, G::Expr)
    unpack_expr = Meta.parse(string(join(string.(p), ","), ",=params"))
    anonf = @eval ((t, params) -> begin $unpack_expr; $G; end)
    (t, params_numbers) -> ccall( @cfunction(  $anonf,  Float64, (Float64, Vector{Float64})).ptr , Float64, (Float64, Vector{Float64}), t, params_numbers)
end
function DM5v(p::Array{Symbol}, G::Expr)
    unpack_expr = Meta.parse(string(join(string.(p), ","), ",=params"))
    anonf = @eval ((t, params) -> begin $unpack_expr; @. $G; end)
    (t, params_numbers) -> ccall( @cfunction(  $anonf,  Vector{Float64}, (Vector{Float64}, Vector{Float64})).ptr , Vector{Float64}, (Vector{Float64}, Vector{Float64}), t, params_numbers)
end

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

No branches or pull requests

2 participants