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

Update Mlucas.c, mi64.c for correct modular division (small scalars) #23

Merged
merged 29 commits into from
Jun 5, 2024

Conversation

xanthe-cat
Copy link
Collaborator

@xanthe-cat xanthe-cat commented Apr 13, 2024

Small fix, for PRP bases other than 3, to ensure the modular division by the square of the base at the end of a PRP test is not subject to a rounding error (bases 7, 14, 27, 28, and 29 are susceptible among the possible PRP bases less than 32). The rounding error for these bases appears in the mi64_div_by_scalar64 function of mi64.c. We also modify the Mlucas.c code to permit PRP bases other than 3 by disabling the ASSERT at line 698 (which would apply to both Mersenne and Fermat exponents) and instituting a similar check later, but only for Fermat numbers (since Mlucas always uses base 3 for the Pépin test).
This fixes #18, fixes #27, as well as committing the Fermat testing documentation to the repository which fixes #1.

Small fix, for PRP bases other than 3, to ensure the modular division by the square of the base at the end of a PRP test is not subject to a rounding error (bases 7, 27, 28, and 29 are susceptible among the possible PRP bases less than 32).
Make a tiny addition to `fquo` in the second limb of the modular division, in the case where a rounding error from the division results in the quotient lying between 0.999...999 (14 nines) and 1.0.
@xanthe-cat xanthe-cat added bug Something isn't working enhancement New feature or request labels Apr 13, 2024
Tweaking the previous assertion for bases other than 3 to apply only to Suyama tests.
src/mi64.c Outdated
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

More discussion on this fix (whether this is an appropriate way to resolve the float to int conversion issue) is over at issue #18.

A few tweaks to the comments
Added warning to stderr if round-off error close to an integer encountered.
Extensive documentation on testing Fermat numbers with Mlucas (this pulls together a number of documented and undocumented information about Mlucas from various sources).
@xanthe-cat
Copy link
Collaborator Author

I’ve added in the Fermat documentation (and some small tweaks to the config script) from issue #1 as this is now ready to be added to the repository, whatever final disposition we reach on the status of whatever modification is desirable to mi64.c.

@xanthe-cat xanthe-cat mentioned this pull request Apr 20, 2024
Copy link
Member

@tdulcet tdulcet left a comment

Choose a reason for hiding this comment

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

Thanks for your work on the Fermat number documentation. I just had some minor feedback. Feel free to add a link to the main README as well.

docs/Fermat-testing.md Outdated Show resolved Hide resolved
docs/Fermat-testing.md Outdated Show resolved Hide resolved
docs/Fermat-testing.md Outdated Show resolved Hide resolved
docs/Fermat-testing.md Outdated Show resolved Hide resolved

The `worktodo` format for the Suyama test is:
```
PRP=N/A,1,2,<2^m>,+1,99,0,3,5,"known_factor_1[,known_factor_2,...]"
Copy link
Member

Choose a reason for hiding this comment

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

It might help to explain more of these parameters, especially if we now support other PRP bases:

PRP=N/A,1,2,<2^m>,1[,how_far_factored,tests_saved[,base,residue_type[,"known_factors"]]]

The plus in the +1 is optional and assumed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I’m a bit on the fence about this; I don’t want to raise the issue of different bases in this context since the worktodo format for the Pépin test does not support bases other than 3; and choosing a different base for composite numbers always involves obtaining a completely different set of final residues.
(Also I like the plus in +1 to clearly indicate what it’s doing following the exponent.)

Copy link
Member

Choose a reason for hiding this comment

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

(Yes, I like the +1 as well, I just thought I should note that it is not strictly required by the format.)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also: known_factors are mandatory for running a Suyama test, so the optional brackets disappear, and presently only residue_type 5 happens to be supported. Since you typically don’t want Mlucas to spontaneously decide to run P–1 prior to the PRP test, this sort of determines all of the variables preceding the factors:

PRP=N/A,1,2,<2^m>,1,how_far_factored,tests_saved,base,residue_type,"known_factors"

Copy link
Member

Choose a reason for hiding this comment

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

Some users may want to run a PRP test on one of the (three) supported Fermat numbers without known factors, in which case maybe some of the parameters could potenchally be useful.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, interesting, thanks for the clarification.

Just a random aside from reading #4, since you write a lot of complex math formulas, GitHub supports LaTeX syntax, if you have used that before. See preda/gpuowl#278 for some examples.

Copy link
Collaborator Author

@xanthe-cat xanthe-cat Apr 23, 2024

Choose a reason for hiding this comment

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

The last time I seriously used $\TeX$ or $\LaTeX$ was in my Honours year, which is now thirty years in the past… I used to have a copy of Lamport’s book which got lost somewhere over various house moves.
I’m investigating how the Pépin test could be adapted for other bases (not all possible bases give a determinative result), so have been running PRP tests with the cofactor test following on; the main problem is the lack of specification for the base in the worktodo format. I coded other bases into my customised version of Gary’s cofact utility and it does appear the Mlucas code works correctly for Fermat modular squaring and cofactor testing in other bases, as I obtained identical Suyama results for base 5 tests of $F_{15}$ and $F_{19}$.

Copy link
Member

Choose a reason for hiding this comment

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

Interesting, thanks again for testing all of this. Regarding support for other bases, probably the easiest solution would be to update the existing PRP=/PRPDC= formats to fully support Fermat numbers, but as you noted above, this could still require a lot of changes.

I had not heard of Gary’s cofact utility, but we could always create a repository in this GitHub organization to store it, along with your customized version, if that would be helpful.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am amenable to adding a repository for GitHub but I would like Gary’s approval before doing so – and he was responsible for all versions before 0.6, which is the earliest I have a copy of. It’s a relatively simple Makefile and single C source file, but it would be nice to have all of the previous versions for populating blame with useful stuff; my fork splits from 0.6 and is now at 0.74c (the c stands for “Cathy”) while Gary is somewhere beyond 0.8.1.

Copy link
Member

Choose a reason for hiding this comment

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

I can send Gary a message and ask if he would be OK moving the development of cofact to GitHub. We could then host your fork either in a separate repository or in a separate branch in the same repository, which ever you preferred. Unlike with Mlucas which is currently community maintained, you and Gary would have complete control over the cofact repository.

Even if Gary does not want to use GitHub, we could always host a mirror, as I do for the other Prime Search related programs. However, in this case I do not believe it could automatically be updated, as the downloads are only on the forum and not a website that could be scrapped, so it would be better to move the development to GitHub if possible.

docs/Fermat-testing.md Outdated Show resolved Hide resolved
xanthe-cat and others added 11 commits April 20, 2024 20:57
Link within document as per suggestion

Co-authored-by: Teal Dulcet <[email protected]>
A few tweaks as suggested by Teal.
One small amendment mprime actually does support Pépin tests (though it is handled somewhat awkwardly as it does not generate a certificate proof of the computation; but at least you do get a Res64).
Added a link to docs/Fermat-testing.md
Explicitly replacing K with kilobytes (FFT length)
Update to Gerbicz’s nsquares integrity check, which assumes the PRP base is always 3.
Fix an ASSERT statement I mangled in the previous commit (that I mistakenly thought behaved like printf)
Successfully tested F13 with the 2K FFT, 8 8 16 radset
Eliminated 1K FFT, as I am now convinced 2K is the smallest possible workable FFT, which can support F13, F14, and F15. However, 2K requires fiddly tweaking of the Mlucas -f command that makes it a “one-off”.
Updated to add 2K FFT
if statement for F15 / 2K FFT
Consistency with assert around line 4100
xanthe-cat and others added 4 commits April 23, 2024 18:13
@tdulcet
Copy link
Member

tdulcet commented Apr 23, 2024

I made a simplification to the config-fermat.sh script in 4341a7e, so avoid duplicating the Mlucas command.

For future reference, when you are just updating the documentation or code comments and do not need to run the CI to test the changes, you can add [skip ci] (or one of these other strings) to your commit message to skip it.

Substitute printing PRP_base in ASSERT with actual value by using cbuf.
[skip ci]
Tweak to help.txt info
The if condition needed to be inverted, we want to possibly invoke an ASSERT if we do not have equality.
src/Mlucas.c Outdated Show resolved Hide resolved
[skip ci]
Adding Teal's suggestions.
Length of the residue in the arrtmp array is j, not i, so the SH 2^35-1 and 2^36-1 residues are not being calculated from the full residue.
@@ -2432,7 +2433,7 @@ with the default #threads = 1 and affinity set to logical core 0, unless user ov
// by base and check that remainder 0. Note that we do want the quotient now, as that is our reside/base:
mi64_div(c_uint64_ptr, &itmp64, j+1,1, arrtmp,&rmodb); ASSERT(HERE, rmodb == 0ull,"After short-div, R != 0 (mod B)");
// And recompute the S-H residues:
res_SH(arrtmp,i,&Res64,&Res35m1,&Res36m1);
res_SH(arrtmp,j,&Res64,&Res35m1,&Res36m1);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this value should be j, judging by the data I’ve looked at j usually is equal to i+1, so the calculation of the mod 2^35-1 and mod 2^36-1 residues is not encompassing the entire length of the arrtmp array. This partially resolves #27.

We refresh the 2^35-1 and 2^36-1 residues for Mersenne exponents (these values were not passed in by the Suyama_CF_PRP call).
@@ -3310,6 +3311,8 @@ uint32 Suyama_CF_PRP(uint64 p, uint64*Res64, uint32 nfac, double a[], double b[]
/*A*/ ierr = func_mod_square(a, (int*)ci, n, ilo,ihi, 0ull, p, scrnFlag, tdiff, TRUE, 0x0);
convert_res_FP_bytewise(a, (uint8*)ci, n, p, Res64, &Res35m1, &Res36m1); // Overwrite passed-in Pepin-Res64 with Fermat-PRP one
snprintf_nowarn(cbuf,STR_MAX_LEN,"MaxErr = %10.9f\n",MME); mlucas_fprint(cbuf,1);
} else if (MODULUS_TYPE == MODULUS_TYPE_MERSENNE) { // Mersenne PRP-CF doesn't have the Res35m1 or Res36m1 values passed in,
res_SH(ci,n,&itmp64,&Res35m1,&Res36m1); // so we refresh these; see https://github.com/primesearch/Mlucas/issues/27
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This resolves the remaining part of #27, as the Suyama (A) value should print with correct Res35m1 and Res36m1 values. (Res64 is already correct so we don’t “re_update” it by referencing itmp64 instead.)

src/Mlucas.c Outdated Show resolved Hide resolved
@tdulcet tdulcet requested a review from gary641 May 5, 2024 19:43
Copy link
Collaborator

@ldesnogu ldesnogu left a comment

Choose a reason for hiding this comment

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

The change looks good to me.

@tdulcet
Copy link
Member

tdulcet commented Jun 5, 2024

The change looks good to me.

Just note that you would need to check the "Approve" radio button when writing the review to allow @xanthe-cat to merge this. Each PR needs at least one approving review.

@ldesnogu
Copy link
Collaborator

ldesnogu commented Jun 5, 2024

Just note that you would need to check the "Approve" radio button when writing the review to allow @xanthe-cat to merge this. Each PR needs at least one approving review.

I would if I could see it :-) Sorry, I'm a newbie.

EDIT: finally found it, sorry again...

Copy link
Collaborator

@ldesnogu ldesnogu left a comment

Choose a reason for hiding this comment

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

OK let's approve it.

@gary641
Copy link
Collaborator

gary641 commented Jun 5, 2024

This is in a section of the code I am not familiar with. So I will trust Cathy's changes!

@xanthe-cat xanthe-cat merged commit eec1757 into main Jun 5, 2024
@xanthe-cat xanthe-cat deleted the modular-division-bugfix branch June 5, 2024 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working enhancement New feature or request
Projects
None yet
4 participants