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

Validate arguments to ListPerm, and turn it into a kernel function to make it faster #5566

Merged
merged 3 commits into from
Jan 10, 2024

Conversation

fingolfin
Copy link
Member

Resolves #4205

In that issue, @frankluebeck was concerned about performance overhead for validating the arguments. I measure it at about 5% on my laptop (going from 167 nanoseconds to 176 ns), which I personally consider fine. But to avoid any argument about that, I just rewrote it as a kernel function, after which it takes 21 ns, i.e., 8 times faster, including full argument validation.

@fingolfin fingolfin added kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements topic: kernel topic: library labels Jan 9, 2024
Copy link
Contributor

@james-d-mitchell james-d-mitchell left a comment

Choose a reason for hiding this comment

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

This looks like it'll be ok with a one line change (degree -> largest moved point). I'm not sure if maybe OnTuplesPerm suffers from the same issue.

lib/permutat.g Show resolved Hide resolved
lib/permutat.g Show resolved Hide resolved
src/permutat.cc Outdated
UInt lmp; // largest moved point
UInt i; // loop variable

lmp = DEG_PERM<T>(perm);
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess from the variable name lmp that this is meant to be the largest moved point, right? If so, then this isn't correct I don't think. The degree of a permutation is the number of entries in the array storing the permutation, and this can be completely different from the largest moved point. For example if you do:

gap> x := (1, 70000);
(1,70000)
gap> y := x * x ^-1;
()

Then the degree of y is 70000 while the largest moved point is 0 (this certainly used to be the case, and the fact that y is in IsPerm4Rep seems to indicate that it still is).

Copy link
Member Author

Choose a reason for hiding this comment

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

You are absolutely right. I'll add the test case and fix the PR. Thanks for carefully checking, much appreciated!

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed, see line 1112

Copy link
Contributor

Choose a reason for hiding this comment

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

This fix isn't complete -- lmp can still be larger than len if len==0, and cause a segfault. For example:

x:=(1,2,3,10000);
y:=(1,10000);
ListPerm(x*y);

(This won't crash immediately, but will if you keep using GAP, as we have written off into as yet unused space).

Maybe just remove the else from 1113, to make sure lmp is never larger than len?

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks, fixed now as well

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've also revised the code some more, renamed lmp, etc.

src/permutat.cc Outdated Show resolved Hide resolved
Makes ListPerm about 5% slower on my system. Indeed, before this patch:

    gap> pi:=(1,2,3,4);;GASMAN("collect");;
    gap> for i in [1..10^7] do ListPerm(pi); od; time;
    1670

After this patch:

    gap> pi:=(1,2,3,4);;GASMAN("collect");;
    gap> for i in [1..10^7] do ListPerm(pi); od; time;
    1760

If there is concern about this, then one could simply turn ListPerm into
a kernel function, which I estimate would make it about 5 times faster,
based on this:

    gap> r:=[1..4];;pi:=(1,2,3,4);;GASMAN("collect");;
    gap> for i in [1..10^7] do OnTuples(r,pi); od; time;
    373
@fingolfin fingolfin force-pushed the mh/ListPerm branch 3 times, most recently from 81435eb to 7496afa Compare January 10, 2024 01:55
@ChrisJefferson
Copy link
Contributor

I'm now happy for this to be merged

@fingolfin
Copy link
Member Author

@ChrisJefferson then please approve (and I'll wait some more before merging in case @james-d-mitchell has anything to add)

Copy link
Contributor

@james-d-mitchell james-d-mitchell left a comment

Choose a reason for hiding this comment

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

No more comments, merge away

@fingolfin fingolfin enabled auto-merge (squash) January 10, 2024 09:16
@fingolfin fingolfin merged commit c4482be into gap-system:master Jan 10, 2024
22 checks passed
@fingolfin fingolfin deleted the mh/ListPerm branch January 10, 2024 09:16
@fingolfin fingolfin added release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes topic: performance bugs or enhancements related to performance (improvements or regressions) labels Jan 22, 2024
@fingolfin fingolfin changed the title Add argument validation to ListPerm, and turn it into a kernel function to make it faster Validate arguments to ListPerm, and turn it into a kernel function to make it faster Jan 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements release notes: use title For PRs: the title of this PR is suitable for direct use in the release notes topic: kernel topic: library topic: performance bugs or enhancements related to performance (improvements or regressions)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ListPerm doesn't check its arguments, can give nonsense
3 participants