Zulip Chat Archive
Stream: general
Topic: simps is very slow
Eric Wieser (Apr 29 2021 at 08:26):
The @[simps mul]
attribute on docs#direct_sum.ghas_mul.of_add_subgroups is making the definition very slow; profiler
says:
elaboration of ghas_mul.of_add_subgroups took 184ms
type checking of ghas_mul.of_add_subgroups took 54.6ms
decl post-processing of ghas_mul.of_add_subgroups took 44.3s
Is there an easy way to see what's going on here?
Floris van Doorn (Apr 30 2021 at 18:59):
Investigating this now. Running the profiler on the command
run_cmd tactic.try_for 100000 (simps_tac ``ghas_mul.of_add_subgroups {rhs_md := semireducible} ["mul"] tt)
does not give what I expected. Apparently 99+% of the time is spent in the tactic docs#tactic.mk_mapp.
I expect this has something to do with the fact that the right hand side of the generated lemma is still a (relatively) complicated structure. This is intended, right?
Eric Wieser (Apr 30 2021 at 19:28):
No, I was hoping it would unfold the add_monoid_hom on the RHS
Eric Wieser (Apr 30 2021 at 19:29):
I added manual versions of the lemmas in #7403
Eric Wieser (Apr 30 2021 at 19:30):
Thanks for investigating though
Eric Wieser (Apr 30 2021 at 19:32):
I think it probably loses lots of time unifying the dependent typeclasses; indeed the submodule
def was much faster than the subgroup one I drew attention to, presumably because it doesn't need to match indexed families of derived typeclasses
Floris van Doorn (Apr 30 2021 at 20:03):
@[simps mul]
tells simps
to generate the lemmas by only applying the projection mul
, no nested projections (in other words, not applied to a
and b
).
If you just run @[simps]
without arguments, it will generate a lemma applied to a
and b
, but it will also apply the coercion from subtypes. To get the lemmas you want (modulo name of the lemma), run @[simps mul_apply_apply]
. You could consider doing that (if you don't mind that the name is uglier). These other lemmas are also generated very quickly.
Floris van Doorn (Apr 30 2021 at 20:05):
I am still investigating further. The issue is indeed related to the add_comm_monoid
structure on (carriers i)
and (carriers i).to_add_submonoid
.
I can try to improve simps
to not use mk_mapp
there. I believe I have all the information there in the tactic, so I could just use expr.app
manually.
Floris van Doorn (Apr 30 2021 at 20:06):
I minimized the original problem to
import group_theory.subgroup
set_option old_structure_cmd true
structure my_add_monoid_hom (M : Type*) (N : Type*) [add_comm_monoid M] [add_comm_monoid N] :=
(to_fun : M → N)
structure ghas_mul (A : Type*) [add_comm_monoid A] :=
(mul : my_add_monoid_hom A A)
section shorthands
variables {R : Type*}
@[simps mul]
def ghas_mul.of_add_submonoids [add_comm_group R] (carriers : add_submonoid R) : ghas_mul carriers :=
{ mul := { to_fun := λ x, x } }
-- @[simps? mul {rhs_md := semireducible}]
def ghas_mul.of_add_subgroups [add_comm_group R] (carriers : add_subgroup R) : ghas_mul carriers :=
ghas_mul.of_add_submonoids carriers.to_add_submonoid
Floris van Doorn (Apr 30 2021 at 20:55):
The slowdown of the original problem is fixed in #7432.
I didn't completely figure out the bottleneck, but it was easy to remove the offending mk_mapp
.
Eric Wieser (Apr 30 2021 at 21:30):
Perhaps we should allow the syntax @[simps mul_apply_apply->mul]
to address the ugly name problem?
Eric Wieser (Apr 30 2021 at 21:30):
(with a unicode arrow to match "initialize_simps_projections")
Floris van Doorn (Apr 30 2021 at 21:39):
You can actually already do this unformly:
def ghas_mul.simps.apply [has_add ι] [Π i, add_comm_monoid (A i)] [ghas_mul A] {i j : ι}
(x : A i) (y : A j) : A (i + j) :=
ghas_mul.mul x y
initialize_simps_projections ghas_mul (mul_to_fun_to_fun → apply, -mul)
Except... that fails. These structures are definitely stress-testing @[simps]
:)
Floris van Doorn (Apr 30 2021 at 21:39):
The syntax @[simps mul_apply_apply->mul]
is probably also useful, and was already on the wishlist #5489
Floris van Doorn (Apr 30 2021 at 22:46):
After #7433 you should be able to write the following, and then @[simps]
(or equivalently @[simps mul]
) will generate the simp lemmas you want with the correct name.
def ghas_mul.simps.mul [has_add ι] [Π i, add_comm_monoid (A i)] [ghas_mul A] {i j : ι}
(x : A i) (y : A j) : A (i + j) :=
ghas_mul.mul x y
initialize_simps_projections ghas_mul (mul → mul', mul_to_fun_to_fun → mul, -mul')
-- Explanation of the last line: the composite projection `mul_to_fun_to_fun` should be called `mul`. Furthermore, we don't generate simp-lemmas that just apply the single projection `mul`. We rename this single projection, because we want to call the composition of 3 projections `mul`.
Last updated: Dec 20 2023 at 11:08 UTC