Zulip Chat Archive
Stream: general
Topic: type class slowdown: mv_polynomial algebras
Rob Lewis (Jul 20 2020 at 13:49):
import data.mv_polynomial
universes u v w
section
variables {σ : Type u} (R : Type v) [comm_ring R]
(A : Type w) [comm_ring A] [algebra R A]
set_option trace.class_instances true
#check (infer_instance : algebra R (mv_polynomial σ R))
end
The type class search here takes ~2 seconds on my laptop. It's definitely the algebra
search that's slow, elaborating the type is fine. What's strange is the search succeeds in two steps. It fails to unify the target with algebra R A
, and then finds the corect instance mv_polynomial.algebra
. These respectively fail and succeed instantly when I try them outside of the type class search.
Rob Lewis (Jul 20 2020 at 13:49):
This seems to be fallout from https://github.com/leanprover-community/mathlib/commit/ce48b6ba77a02430c098f26f3fcc3c11e516179b . The search is instant before that.
Rob Lewis (Jul 20 2020 at 13:49):
But I can't tell why it's slow now. Any ideas?
Johan Commelin (Jul 20 2020 at 14:16):
This one is instant:
import data.mv_polynomial
universes u v w
section
variables {σ : Type u} (R : Type v) [comm_semiring R]
(A : Type w) [comm_ring A] [algebra R A]
set_option trace.class_instances true
#check (infer_instance : algebra R (mv_polynomial σ R))
end
Johan Commelin (Jul 20 2020 at 14:17):
The diff: comm_semiring R
instead of comm_ring R
Sebastien Gouezel (Jul 20 2020 at 14:19):
It's really strange, because the instance search output is pretty short in any case, and for the same question apply_instance
works instantaneously.
I have no clue about what's going on.
Rob Lewis (Jul 20 2020 at 14:25):
It's not the comm_semiring -> semiring search that's at fault. This def is instant and doesn't affect the bad search.
@[instance, priority 1000000] def csr : comm_semiring R := infer_instance
Rob Lewis (Jul 20 2020 at 14:25):
Which makes me suspect that some instance is taking a long time to unify or fail to unify.
Rob Lewis (Jul 20 2020 at 14:25):
But I'm not sure how to debug this.
Sebastien Gouezel (Jul 20 2020 at 14:33):
How do you explain that
import data.mv_polynomial
universes u v w
section
variables {σ : Type u} (R : Type v) [comm_ring R]
set_option trace.class_instances true
noncomputable lemma foo : algebra R (mv_polynomial σ R) :=
let a := (infer_instance : algebra R (mv_polynomial σ R)) in
infer_instance
end
is also instant?
Rob Lewis (Jul 20 2020 at 14:36):
My guess is a caching thing. The type class cache should be frozen after the :=
.
Sebastien Gouezel (Jul 20 2020 at 14:41):
Yes, it's a cache thing:
import data.mv_polynomial
universes u v w
section
set_option trace.class_instances true
noncomputable example {σ : Type u} (R : Type v) [comm_ring R] : true :=
begin
unfreezingI {let a := (infer_instance : algebra R (mv_polynomial σ R)) },
trivial
end
end
is also slow.
Johan Commelin (Jul 20 2020 at 14:44):
Now I have a headache...
Sebastien Gouezel (Jul 20 2020 at 14:46):
And the profiler is totally unhelpful:
set_option profiler true
lemma foo {σ : Type u} (R : Type v) [comm_ring R] : true :=
begin
unfreezingI { let a := (infer_instance : algebra R (mv_polynomial σ R)) },
trivial
end
gives the output
elaboration: tactic execution took 4.25s
num. allocated objects: 35
num. allocated closures: 117
4249ms 100.0% tactic.to_expr
4249ms 100.0% tactic.interactive.let._lambda_1
4249ms 100.0% _interaction._lambda_3
4249ms 100.0% tactic.focus1
4249ms 100.0% tactic.step
4249ms 100.0% tactic.unfreezing._lambda_2
4249ms 100.0% tactic.istep._lambda_1
4249ms 100.0% tactic.istep
4249ms 100.0% _interaction._lambda_2
4249ms 100.0% scope_trace
4249ms 100.0% _interaction
Rob Lewis (Jul 20 2020 at 15:05):
So this is as minimal as I have it.
import data.mv_polynomial
universes u v w
section
variables {σ : Type u} (R : Type v) [cr : comm_ring R]
include cr
noncomputable def p : semiring (mv_polynomial σ R) := infer_instance
#check (infer_instance :
@algebra R (@ mv_polynomial σ R (@comm_ring.to_comm_semiring _ cr))
(@comm_ring.to_comm_semiring _ cr) (@p σ R cr))
There's exactly one type class search in the #check
. It tries to apply exactly one instance.
Rob Lewis (Jul 20 2020 at 15:07):
Uhm. And using by apply_instance
instead of infer_instance
makes it instant.Maybe because this freezes the instance cache?
Sebastien Gouezel (Jul 20 2020 at 15:13):
Yes, getting into tactic mode should freeze the cache.
Should we invoke @Gabriel Ebner ?
Rob Lewis (Jul 20 2020 at 15:16):
Poor Gabriel is too popular for his own health, hah.
Jannis Limperg (Jul 20 2020 at 15:26):
I should walk over and remind him that all this research business is interfering with his Lean maintenance duties. :upside_down:
Sebastien Gouezel (Jul 20 2020 at 15:28):
Isn't he on holidays? We should definitely not interfere with the holidays!
Gabriel Ebner (Jul 20 2020 at 16:04):
Is this lean#397? If not, please file an issue. I'm back from holidays but occupied by another project for the next two days.
Rob Lewis (Jul 20 2020 at 16:10):
It's not directly the same but could be related. I'll file it separately for when you have time. Thanks as always!
Floris van Doorn (Jul 20 2020 at 17:15):
Rob Lewis said:
Uhm. And using
by apply_instance
instead ofinfer_instance
makes it instant.Maybe because this freezes the instance cache?
I've noticed infer_instance
being worse than by apply_instance
in multiple cases. I think in those cases usually infer_instance
fails and by apply_instance
succeeds. My personal workaround is just to never use infer_instance
anymore.
Johan Commelin (Jul 20 2020 at 17:15):
But this is a MWE extracted from a situation where we use neither, I think
Johan Commelin (Jul 22 2020 at 12:23):
This is biting me again :sad:
Johan Commelin (Jul 22 2020 at 16:37):
@Gabriel Ebner do you think that lean#403 also fixes this issue?
Gabriel Ebner (Jul 23 2020 at 09:30):
I think so.
Johan Commelin (Jul 23 2020 at 09:32):
@Gabriel Ebner Cool! Any idea about when you want to release a new Lean? (-;
Last updated: Dec 20 2023 at 11:08 UTC