Zulip Chat Archive

Stream: mathlib4

Topic: shortcut for `Seminorm.instMulAction`?


Jireh Loreaux (Aug 02 2023 at 16:50):

docs#Seminorm.instMulAction has the following very unfortunate behavior:

import Mathlib

open scoped NNReal

variable {๐•œ E : Type _} [NormedField ๐•œ] [AddCommGroup E] [Module ๐•œ E]

set_option synthInstance.maxHeartbeats 27000 in -- times out otherwise
#synth MulAction โ„โ‰ฅ0 (Seminorm ๐•œ E) -- Seminorm.instMulAction

That is, it is timing out on what I believe is the most common use case. This doesn't show up in mathlib currently because, while it's relatively close to the heartbeat limit where it occurs, not enough of mathlib is imported to push it over the limit. However, various changes can push it over (e.g., #6310). So, what should we do about this? Should we add a shortcut instance for the usual case R := โ„โ‰ฅ0 in docs#Seminorm.instMulAction ?

On a separate note, while writing down the mwe above, I came across something I don't know how to explain: adding explicit universe parameters allows us to the lower the heartbeat limit (both examples are taken to the nearest thousand). Is there a reason this should be the case?

variable {๐•œ : Type u} {E : Type v} [NormedField ๐•œ] [AddCommGroup E] [Module ๐•œ E]

set_option synthInstance.maxHeartbeats 22000 in -- times out otherwise
#synth MulAction โ„โ‰ฅ0 (Seminorm ๐•œ E) -- Seminorm.instMulAction

Matthew Ballard (Aug 02 2023 at 16:53):

Explicit universes have been seen to speed things up during the port. As to the exact reason...

Matthew Ballard (Aug 02 2023 at 16:59):

The term for Function.Injective.mulAction shrinks by about 25% (measured in terms of lines with pp.explicit) if you delete the smul field.

Eric Wieser (Aug 02 2023 at 17:12):

I think we should aim to replace X : Type _ with X : Type uX everywhere in mathlib (or write an elaborator to do it for us)

Matthew Ballard (Aug 02 2023 at 17:12):

Didn't @Kyle Miller do this?

Matthew Ballard (Aug 02 2023 at 17:13):

I agree that Type _ should disappear (as currently functioning).

Eric Wieser (Aug 02 2023 at 17:13):

Asking Lean to waste time solving universe constraints is kinda silly when maybe 95% of the time there is nothing to solve, of which maybe 1% it introduces actual bugs

Kyle Miller (Aug 02 2023 at 17:18):

https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/function.2Ecombine/near/362309752 is an elaborator for Type* and Sort* (and just a day or two ago I was trying to remember the name of levelMVarToParam and where I'd last used it).

Kyle Miller (Aug 02 2023 at 17:19):

I'm happy to make a PR if we think using these in mathlib is a good idea, versus using explicit universe variables or some other solution.

Matthew Ballard (Aug 02 2023 at 17:22):

I would be interested in seeing the benchmark results from a large-scale swap.

Kyle Miller (Aug 02 2023 at 17:26):

It'd be neat if we could have Type* mean Type ?u for some unspecified universe parameter (not an expression, but an actual parameter). That is, have a new kind of level metavariable that can only unify with level parameters or other such metavariables. I feel like this is what I'd expect out of Type*, where writing (X Y : Type*) doesn't mean that X and Y are definitely in different universes.

Eric Wieser (Aug 02 2023 at 17:27):

I don't think that's a problem we really have. The big problem is that no one wants to write out the word Type u$n 10 times, so falls back on Type _

Eric Wieser (Aug 02 2023 at 17:28):

In the rare case where we actually do want to constrain the variables I think spelling things out the long way is fine.

Kyle Miller (Aug 02 2023 at 17:29):

I'm thinking about variable lines where some lemmas along the way are specialized to some of the types being in the same universe

Jireh Loreaux (Aug 02 2023 at 17:29):

I think that's relatively uncommon (at least in my part of mathlib)

Notification Bot (Aug 02 2023 at 17:32):

A message was moved from this topic to #maths > Proving extentionality for a category structure by Kyle Miller.

Eric Wieser (Aug 02 2023 at 17:35):

I'd rather see a very explicit marker on the lemma that something fishy is happening with universes

Kyle Miller (Aug 02 2023 at 17:35):

Eric Wieser said:

I think spelling things out the long way is fine.

When you say "is fine" do you mean "is better" or "is acceptable"?

Haven't you ever had bunch of type arguments and you decide you want to give them explicit universe levels, and it's a little annoying to split up the binder and maybe permute some of the arguments?

Eric Wieser (Aug 02 2023 at 17:36):

It's extraordinarily rare that I don't want to put all my types in different and unrelated universes

Matthew Ballard (Aug 02 2023 at 17:44):

The current situation is bad enough that I now instinctively want to break out X ... Z : Type _ whenever I see it. I think a change will have noticeable effect.

Jireh Loreaux (Aug 02 2023 at 19:48):

So, does anyone have an answer to the first part of my question?

Matthew Ballard (Aug 05 2023 at 01:46):

I took Kyle's Type* and tried to ruthlessly uproot Type _ from mathlib in #6370.

It had noticeable effect.

Matthew Ballard (Aug 05 2023 at 02:46):

Probably quite a few heart beat bumps can now be excised.

Matthew Ballard (Aug 05 2023 at 02:47):

An example: I deleted both bumps in RingTheory.ClassGroup.

Sebastien Gouezel (Aug 05 2023 at 07:25):

There's a lot of green there (really a lot!), but maxrss goes up by 192.3% which is a little bit surprising to me.

Scott Morrison (Aug 05 2023 at 07:34):

-1.37% wall clock!

Matthew Ballard (Aug 05 2023 at 10:18):

Another surprising things: Lean is working surprisingly hard on universe unification.

Maybe @Sebastian Ullrich can help us interpret the results.

Matthew Ballard (Aug 05 2023 at 10:23):

There are also some big outliers amongst the files. Analysis.InnerProductSpace.Basic is +128.2%. These are probably our fault but I canโ€™t explain it at the moment

Sebastian Ullrich (Aug 05 2023 at 11:10):

It would be interesting to analyze these outliers, say with something like \time -v lake env lean --profile $FILE before and after the change. I can only assume that the maxrss increase is driven by a compilation regression in one of these files. Which in itself is surprising as compilation should not really care about universes.

Matthew Ballard (Aug 05 2023 at 11:55):

Before

After

Matthew Ballard (Aug 05 2023 at 11:57):

Key line:

compilation of ContinuousLinearMap.toSesqForm took 75.7s

Matthew Ballard (Aug 05 2023 at 12:03):

But you can also see how the changes cut into the time for tc inference

Sebastian Ullrich (Aug 05 2023 at 12:12):

Also a 10x maxrss increase, which matches the overall maxrss of the run. So indeed it must be the runaway compilation step.

Sebastian Ullrich (Aug 05 2023 at 13:26):

I took a quick look, there is no trace.compiler.input output at all on master. Could it be that the change suddenly made the definition computable?

Eric Wieser (Aug 05 2023 at 13:35):

Does docs#ContinuousLinearMap.toSesqForm claim it's currently computable? (Edit: yes)

Matthew Ballard (Aug 05 2023 at 13:36):

The one above it is being compiled in both versions.

Matthew Ballard (Aug 05 2023 at 13:37):

Would code not get generated without a warning?

Matthew Ballard (Aug 05 2023 at 13:39):

The universe signatures of the two versions of the declaration are fairly different I think. Perhaps something computable is synthesized where before it wasnโ€™t

Matthew Ballard (Aug 05 2023 at 13:40):

The other defโ€™s also are compiled more slowly. Just not as huge a difference

Eric Wieser (Aug 05 2023 at 13:46):

What's the new set of universes? The current one looks correct in the docs.

Matthew Ballard (Aug 05 2023 at 13:47):

Hmm. Let me retract that. I donโ€™t see how this could get generalized. I am remembering other declarations I looked at

Matthew Ballard (Aug 05 2023 at 13:50):

But perhaps it still possible that something computable is synthesized where it wasnโ€™t before.

Matthew Ballard (Aug 05 2023 at 13:54):

There are also other outliers. The worst of the remaining:

  • RingTheory.Noetherian
  • Analysis.NormedSpace.Dual
  • Algebra.Category.ModuleCat.Monoidal.Basic

Matthew Ballard (Aug 05 2023 at 13:55):

When I get a chance, I can profile them also. But that might not be for a bit

Matthew Ballard (Aug 05 2023 at 14:19):

Generating code for anything with an IsROrC instance seems strange to me.

Matthew Ballard (Aug 05 2023 at 14:29):

RingTheory.Noetherian

Before

After

Matthew Ballard (Aug 05 2023 at 14:32):

Algebra.Category.ModuleCat.Monoidal.Basic

Before

After

Matthew Ballard (Aug 05 2023 at 14:34):

Analysis.NormedSpace.Dual

Before

After

Matthew Ballard (Aug 05 2023 at 14:38):

Dual seems closest to InnerProductSpace.Basic. The other two each seem different from all others

Matthew Ballard (Aug 05 2023 at 14:46):

Adding noncomputable to toSesqForm on master seems to have no effect on performance in terms of heart beats. Whereas, with the universe changes, it is lightning quick. You can remove the maxHeartbeats bump overall (though no the synth one)

Matthew Ballard (Aug 05 2023 at 15:10):

Also, replacing all Type* with Type _ just in the file cuts the compilation time and maxrss

output

Sebastian Ullrich (Aug 05 2023 at 16:00):

It has something to do with the heartbeat timeout. Perhaps on master the timeout makes the compiler abort early, which makes the noncomputable section mark the definition as noncomputable. But in your PR, the compiler passes that stage without running into the timeout, and then does the actual, long compilation that does not check the timeout.

Matthew Ballard (Aug 05 2023 at 16:19):

It was non computable in mathlib3.

Eric Wieser (Aug 05 2023 at 16:34):

Lean 3 was much worse at deciding computability; it could be poisoned by typeclass assumptions used only for proofs

Matthew Ballard (Aug 05 2023 at 16:39):

So is this a bug or a feature?

Matthew Ballard (Aug 05 2023 at 17:53):

Matthew Ballard said:

So is this a bug or a feature?

By โ€œthisโ€, I mean that weโ€™ve made Lean so fast it thinks it should start doing other things :)

Matthew Ballard (Aug 05 2023 at 17:54):

The whole file in mathlib3 was noncomputable theory.

Matthew Ballard (Aug 05 2023 at 18:19):

Yes, removing noncomputable section from the start of the file on master gives

โ–ถ 1824:5-1824:15: error:
compiler IR check failed at 'TopologicalAddGroup.toUniformSpace._at.ContinuousLinearMap.toSesqForm._spec_9._rarg', error: unknown declaration 'ContinuousLinearMap.toSeminormedAddCommGroup'

Matthew Ballard (Aug 05 2023 at 18:28):

I get the same error on the PR branch so I don't think it is generating any code despite its serious efforts

Matthew Ballard (Aug 06 2023 at 00:04):

Also, trace.compiler.input reports nothing on the PR branch. Furthermore, it seems to short-circuit compilation of toSesqForm completely.

Matthew Ballard (Aug 07 2023 at 03:13):

I went through and poked at all the heart beat bumps with the fix to universes. Here is the diff between before and after

Matthew Ballard (Aug 07 2023 at 03:22):

Coarse count: 65/153 bumps (counting both types) were eliminated. The majority of the those not eliminated were decreased.

Matthew Ballard (Aug 07 2023 at 03:24):

About 30 out of 80 files became bump-free

Matthew Ballard (Aug 07 2023 at 14:53):

If anyone wants to help interpret the diff above, I would appreciate it. Some thoughts:

  • You can get some incredible speed ups. One declaration lost 8000000 heart beats. Some in the millions were completely gone. Even million-level synthInstance.maxHeartbeats(almost) were wiped out. (Checkout our old friend OperatorNorm for fun.)
  • Some other ones were completely inert to the change. (Though I think all increases are user-error.)
  • It seems that synthInstance.maxHeartBeats were wiped at a higher rate than overall bumps. This comports with the 7.5% improvement in tc inference vs the overall 4% improvement in instructions.

As to an explanations, I have some thoughts but nothing I can really support with hard data.

Eric Wieser (Aug 07 2023 at 15:15):

Did we track down the increased memory usage? (or did it go away)

Matthew Ballard (Aug 07 2023 at 15:16):

Lean was trying to compile toSesqForm and spending lots of resources on it. It looks like it doesn't actually build anything -- just heats up your lap.

I don't know the exact reason for why it is happening.

But marking it noncomputable explicitly short circuits it and seems fine for the current purposes

Matthew Ballard (Aug 07 2023 at 15:18):

Matthew Ballard said:

Also, trace.compiler.input reports nothing on the PR branch. Furthermore, it seems to short-circuit compilation of toSesqForm completely.

This was weird

Jireh Loreaux (Aug 26 2023 at 01:00):

This thread got derailed (in a good way!), but does anyone have a suggestion for the original post in this thread?

Matthew Ballard (Aug 26 2023 at 10:30):

lean4#2451 ? It times out around 15000 on #6759 with Type*


Last updated: Dec 20 2023 at 11:08 UTC