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

Add macro trixi_include_changeprecision to make a double precision elixir run with single precision #35

Merged
merged 16 commits into from
Jan 28, 2025

Conversation

efaulhaber
Copy link
Member

@efaulhaber efaulhaber commented Dec 23, 2024

This is similar to how Base.include is defined:

include(mod::Module, _path::AbstractString) = _include(identity, mod, _path)
include(mapexpr::Function, mod::Module, _path::AbstractString) = _include(mapexpr, mod, _path)

@efaulhaber efaulhaber added the enhancement New feature or request label Dec 23, 2024
@efaulhaber efaulhaber requested a review from sloede December 23, 2024 19:02
@coveralls
Copy link

coveralls commented Dec 23, 2024

Pull Request Test Coverage Report for Build 12471675311

Details

  • 4 of 4 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.1%) to 95.122%

Totals Coverage Status
Change from base Build 12102967779: 0.1%
Covered Lines: 78
Relevant Lines: 82

💛 - Coveralls

Copy link

codecov bot commented Dec 23, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.54%. Comparing base (91eb18c) to head (4dc5480).
Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #35      +/-   ##
==========================================
+ Coverage   95.00%   97.54%   +2.54%     
==========================================
  Files           5        5              
  Lines          80      163      +83     
==========================================
+ Hits           76      159      +83     
  Misses          4        4              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@sloede sloede left a comment

Choose a reason for hiding this comment

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

Fine by me, though I do not really understand most of the changes 😅. Would be good if @ranocha could give the final green light :-)

Copy link
Member

@ranocha ranocha left a comment

Choose a reason for hiding this comment

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

Thanks! Why do you need this functionality?

src/trixi_include.jl Show resolved Hide resolved
src/trixi_include.jl Outdated Show resolved Hide resolved
src/trixi_include.jl Outdated Show resolved Hide resolved
@efaulhaber
Copy link
Member Author

Thanks! Why do you need this functionality?

I want to add a macro trixi_include_changeprecision to TrixiParticles that behaves like trixi_include, but uses ChangePrecision.jl to change the precision of an elixir to Float32 to run it on GPUs.

I could also add this macro to TrixiBase, but so far it will only be used by TrixiParticles.

https://github.com/trixi-framework/TrixiParticles.jl/blob/ef/more-gpu-support/src/util.jl#L138-L163

@efaulhaber efaulhaber requested a review from ranocha January 9, 2025 10:09
@ranocha
Copy link
Member

ranocha commented Jan 9, 2025

Thanks! Why do you need this functionality?

I want to add a macro trixi_include_changeprecision to TrixiParticles that behaves like trixi_include, but uses ChangePrecision.jl to change the precision of an elixir to Float32 to run it on GPUs.

I could also add this macro to TrixiBase, but so far it will only be used by TrixiParticles.

https://github.com/trixi-framework/TrixiParticles.jl/blob/ef/more-gpu-support/src/util.jl#L138-L163

This would be nice to have here

@efaulhaber efaulhaber changed the title Make trixi_include more flexible by allowing a mapping to be passed Add macro trixi_include_changeprecision to make a double precision elixir run with single precision Jan 14, 2025
@efaulhaber
Copy link
Member Author

I now moved the macro from TrixiParticles to this PR.

@efaulhaber efaulhaber requested a review from sloede January 14, 2025 13:17
src/trixi_include.jl Outdated Show resolved Hide resolved
src/trixi_include.jl Outdated Show resolved Hide resolved
Co-authored-by: Erik Faulhaber <44124897+efaulhaber@users.noreply.github.com>
Copy link
Member

@ranocha ranocha left a comment

Choose a reason for hiding this comment

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

Could you please add a test before we merge this PR?

Copy link
Member

@sloede sloede left a comment

Choose a reason for hiding this comment

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

LGTM in general and is certainly an interesting feature!

Before merging, I second @ranocha in that there should be a test for this - maybe using some temporary Julia file that will return a double floating point value but will then be changed to returning a Float32 value?

@efaulhaber
Copy link
Member Author

Back to @ranocha's question:

Why did you choose this order of operations?

I just changed it to first replace assignments and then call mapexpr. This means that ChangePrecision is called on top of the replaced elixir. Thus,

trixi_include_changeprecision(Float32, elixir; density=1000.0)

will make density a Float32.
I think this is the most intuitive and least error-prone option. Especially when writing things where this is less obvious like

trixi_include_changeprecision(Float32, elixir; density=ones(nparticles))

Here, ones will be changed by ChangePrecision to ones(Float32, ...).

I also added tests for this.

@efaulhaber efaulhaber requested review from ranocha and sloede January 16, 2025 10:46
Comment on lines +95 to +107
function replace_trixi_include(T, expr)
expr = TrixiBase.walkexpr(expr) do x
if x isa Expr
if x.head === :call && x.args[1] === :trixi_include
x.args[1] = :trixi_include_changeprecision
insert!(x.args, 2, :($T))
end
end
return x
end

return expr
end
Copy link
Member Author

Choose a reason for hiding this comment

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

One more problem here. This doesn't work when, for some reason, we would include an elixir that looks like this:

using TrixiBase

TrixiBase.trixi_include(...)

It only works when we directly write the elixir as

using TrixiBase

trixi_include(...)

@ranocha any ideas how to fix this?

Copy link
Member

Choose a reason for hiding this comment

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

Can you special case this with something like Symbol("TrixiBase.trixi_include")?

Alternatively, @vchuravy might have an idea how this can be done?

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried, didn't work. Also, we would need to add a special case for each package that re-exports this name.

Copy link
Member

Choose a reason for hiding this comment

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

This will be a GlobalRef(mod, name).

So x.args[1] isa GlobalRef and then check the name and replace it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Doesn't work. x.args[1] isa GlobalRef is false.

Copy link
Member Author

Choose a reason for hiding this comment

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

julia> TrixiBase.trixi_include_changeprecision(Float32, "../TrixiBase.jl/test1.jl")
[ Info: You just called `trixi_include`. Julia may now compile the code, please be patient.
ERROR: LoadError: UndefVarError: `TrixiBase.trixi_include_changeprecision` not defined in `Main`
Suggestion: check for spelling errors or missing imports.

Copy link
Member

Choose a reason for hiding this comment

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

But it looks like TrixiBase.trixi_include_changeprecision is defined... Does your test file create a module? How does it import trixi_include?

Copy link
Member Author

Choose a reason for hiding this comment

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

Idk. The test file just contains this single line:

TrixiBase.trixi_include("test2.jl")

And the error message says we're in Main.

Copy link
Member Author

Choose a reason for hiding this comment

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

Or should we merge it as is and discuss this in an issue? I don't feel like wasting more time on this edge case.

Copy link
Member

Choose a reason for hiding this comment

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

I agree. IMHO if it is possible I'd just hard-code two versions for trixi_include and TrixiBase.trixi_include. If that's not feasible, just put it in the docstring that you need to invoke this in a certain way.

src/trixi_include.jl Show resolved Hide resolved
test/trixi_include.jl Outdated Show resolved Hide resolved
@efaulhaber efaulhaber requested a review from sloede January 16, 2025 16:51
Copy link
Member

@sloede sloede left a comment

Choose a reason for hiding this comment

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

LGTM! Let's wait and see if @vchuravy has an easy solution for the open conversation (if not, we can go ahead anyways)

src/trixi_include.jl Outdated Show resolved Hide resolved
Copy link
Member

@ranocha ranocha left a comment

Choose a reason for hiding this comment

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

Thanks! Let's merge this as it is and discuss possible improvements in an issue

@ranocha ranocha enabled auto-merge (squash) January 28, 2025 08:39
@ranocha ranocha disabled auto-merge January 28, 2025 08:45
@ranocha ranocha merged commit 9595823 into main Jan 28, 2025
15 checks passed
@ranocha ranocha deleted the ef/mapexpr branch January 28, 2025 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants