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

Fix for #596 #597

Merged
merged 16 commits into from
May 7, 2024
Merged

Fix for #596 #597

merged 16 commits into from
May 7, 2024

Conversation

torfjelde
Copy link
Member

@torfjelde torfjelde commented Apr 23, 2024

See #596 for a description of the issue. Fix #596

This PR automates the approach suggested by @willtebbutt, making it so that

@model demo(::Type{TV}=Vector{Float64}) where {TV}

is effectively converted into the current

@model demo(::DynamicPPL.TypeWrap{TV}=DynamicPPL.TypeWrap{Vector{Float64}}()) where {TV}

ensuring that model.args does not involve DataType, leading to significant improvements in type-stability for both the evaluator and the constructor.`

EDIT: Note that this change is a bit annoying as it does introduce "more magic" in DynamicPPL, but I'm personally happy with this for now as it technically fixes a bunch of type stability bugs. If we want to be explicit about what's happening, we can always just remove the magic at a later stage and tell the user to use TypeWrap instead of Type going forward.

@torfjelde
Copy link
Member Author

The type-instabilities had been observed before too, e.g. see the test case now uncommented in this PR, but hadn't investigated it yet and thought it was for different reasons, so big thanks to @willtebbutt for discovering this!

@coveralls
Copy link

coveralls commented Apr 23, 2024

Pull Request Test Coverage Report for Build 8989979287

Details

  • 16 of 16 (100.0%) changed or added relevant lines in 1 file are covered.
  • 130 unchanged lines in 14 files lost coverage.
  • Overall coverage decreased (-2.8%) to 78.739%

Files with Coverage Reduction New Missed Lines %
src/model.jl 1 89.22%
src/sampler.jl 1 94.12%
ext/DynamicPPLForwardDiffExt.jl 1 77.78%
src/contexts.jl 2 77.27%
src/logdensityfunction.jl 2 55.56%
src/compiler.jl 2 93.42%
src/prob_macro.jl 4 84.67%
src/abstract_varinfo.jl 5 82.68%
src/simple_varinfo.jl 6 82.61%
src/context_implementations.jl 8 62.23%
Totals Coverage Status
Change from base Build 8986295028: -2.8%
Covered Lines: 2785
Relevant Lines: 3537

💛 - Coveralls

@torfjelde
Copy link
Member Author

@yebai @devmotion @sunxd3 thoughts on this?

I think the main issue is: do we want to introduce more magic (here we perform a simple transformation on very specific parameters)? As outlined above, I'm pro doing it for now as it will have significant impact on user code (type-stability and perf wise + will make some AD backends much faster) and I consider this a bugfix (given how we spout this pattern as a way of achieving signfiicnat performance gains). Long-term we might want to make these things explicit, but for now I like this.

Copy link
Member

@devmotion devmotion left a comment

Choose a reason for hiding this comment

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

Great!

we can always just remove the magic at a later stage and tell the user to use TypeWrap instead of Type going forward.

I think ideally we would not have to use TypeWrap internally. But IMO the "magic" is better than exposing TypeWrap, I think we should not require users to know about such details (and even if it would be in the docs I am sure the majority of users would unknowingly use Type).

src/compiler.jl Outdated Show resolved Hide resolved
src/compiler.jl Outdated Show resolved Hide resolved
@willtebbutt
Copy link
Member

Does this just require a patch bump?

@torfjelde
Copy link
Member Author

Cheers @devmotion !

Does this just require a patch bump?

Done.

@torfjelde
Copy link
Member Author

torfjelde commented Apr 23, 2024

I've been running some benchmarks locally with ForwardDiff, ReverseDiff, and Zygote, and it doesn't seem like there are any perf improvements 🙃 With the exception of models using @submodel, which was expected to improve signfiicantly (since in that case the return-value being inferred is mucho bueno).

EDIT: But there consistently less memory usage, so it's at least doing something:)

@torfjelde torfjelde enabled auto-merge April 23, 2024 22:59
@sunxd3
Copy link
Member

sunxd3 commented Apr 24, 2024

Love this!

@torfjelde
Copy link
Member Author

So integration tests are failing because we're explicitly testing passing in types as arguments. It does raise the question as to whether we should make this breaking or not 🤔

Thoughts?

@devmotion
Copy link
Member

Can we have both? That is, could we forward f(arg1, ::Type{TV}, ...) to f(arg1, ::TypeWrap{TV}, ...)?

@torfjelde
Copy link
Member Author

torfjelde commented Apr 24, 2024

Can we have both? That is, could we forward f(arg1, ::Type{TV}, ...) to f(arg1, ::TypeWrap{TV}, ...)?

Was thinking about the same. But so now we generate 3 methods instead? And should we issue a dep warning?

Or do we also add an evaluator with this, leading to 4 methods?

@torfjelde
Copy link
Member Author

Hmm on a second thought, I don't think we can 😕

If we try to keep the old method around, we will define the default method twice. Only if we remove the default values for the Type version could we do something like that, but then we're already probably breaking stuff so uncertain if that's worth it 😕

@torfjelde
Copy link
Member Author

tbf there's probably no one using this functionality outside of Turing.jl's own tests, so probably isn't a huge problem to make a breaking change to it

@yebai
Copy link
Member

yebai commented Apr 28, 2024

tbf there's probably no one using this functionality outside of Turing.jl's own tests, so probably isn't a huge problem to make a breaking change to it

Sounds good.

@yebai
Copy link
Member

yebai commented May 5, 2024

Is anything missing here? If not, let's try to get this merged.

src/compiler.jl Outdated
@@ -599,7 +631,7 @@ is_splat_symbol(s::Symbol) = startswith(string(s), "#splat#")
Builds the output expression.
"""
function build_output(modeldef, linenumbernode)
args = modeldef[:args]
args = transform_args(modeldef[:args])
kwargs = modeldef[:kwargs]
Copy link
Member

Choose a reason for hiding this comment

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

I think this should probably be applied to keyword arguments as well?

Suggested change
kwargs = modeldef[:kwargs]
kwargs = transform_args(modeldef[:kwargs])

(not sure if it can be applied directly here in this way)

Copy link
Member Author

Choose a reason for hiding this comment

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

Why? Do we care if we specialize on the kwargs?

Copy link
Member

Choose a reason for hiding this comment

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

IIRC we store them in the same way as pos arguments in the model.

Copy link
Member

Choose a reason for hiding this comment

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

So the Model will generally still operate with DataTypes unless we apply the same fix to kwarga.

Copy link
Member Author

Choose a reason for hiding this comment

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

No you're right 👍 Working on it now

Copy link
Member Author

Choose a reason for hiding this comment

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

Added this 👍

@torfjelde
Copy link
Member Author

torfjelde commented May 6, 2024

Only question: do we make this a breaking release or not? @devmotion thoughts?

Technically it's breaking so I am leaning towards this.

@yebai yebai disabled auto-merge May 6, 2024 17:05
@yebai yebai enabled auto-merge May 6, 2024 17:05
@yebai
Copy link
Member

yebai commented May 6, 2024

Probably better to make this breaking release since it breaks Turing tests anyway

@devmotion
Copy link
Member

I'd also make it a breaking release.

@yebai yebai disabled auto-merge May 7, 2024 18:25
@yebai yebai enabled auto-merge May 7, 2024 18:26
@yebai yebai added this pull request to the merge queue May 7, 2024
@yebai
Copy link
Member

yebai commented May 7, 2024

It seems auto merging is quite fragile — it needs disabling and then re-enabling to fix unknown failures.

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks May 7, 2024
@yebai yebai merged commit 5347acd into master May 7, 2024
11 of 12 checks passed
@yebai yebai deleted the torfjelde/type-instabilities-fixes branch May 7, 2024 20:04
@torfjelde
Copy link
Member Author

Please let the author of the PR perform the merge @yebai ; in this case it was fine, but it's not always the case.

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.

Type-instability when using type-parameters
6 participants