![]() |
![]() |
#1 |
Sep 2002
Database er0rr
11·383 Posts |
![]()
This is another call for a simple 50ish line program to be written with GWNUM to implement Tony Reix's Digraph for 2^n-3:
Code:
for(n=4, 10000, N=2^n-3; S0=8; x=S0; for(i=1, n-1, x=Mod(x^2-2,N)); if(x==S0, print1(n,", ")))
The reason is to write a small program to illustrate the use of GWNUM. I know we could whittle down the LLR source code but I though some one could just write a program. ![]() Last fiddled with by paulunderwood on 2015-08-29 at 22:26 |
![]() |
![]() |
![]() |
#2 |
Just call me Henry
"David"
Sep 2007
Liverpool (GMT/BST)
2·5·599 Posts |
![]()
There are two possibilities. A pfgw script could do what you want. Another option is talking to Jean about adding it to llr.
Both would be much easier than a new program. |
![]() |
![]() |
![]() |
#3 | |
"Dana Jacobsen"
Feb 2011
Bangkok, TH
32×101 Posts |
![]() Quote:
I, for instance, am more interested in doing a BPSW test, then adding a nextprime / prevprime framework. I'm not interested in calling the PFGW executable for each value (Niceky's cglp4 does this), and I don't think a PFGW script will do this properly. I admit there is a "Dear Lazyweb" prefix to this request. |
|
![]() |
![]() |
![]() |
#4 |
Sep 2002
Database er0rr
11·383 Posts |
![]()
I have hacked it! To get it running I needed to "make" llr64 in order to get gwnum.a in place. The following script is put in the root directory of the LLR source tree and compiled with:
Code:
gcc s2.c gwnum/gwnum.a gwnum/gwnum.ld -lm -lpthread -lstdc++ Code:
#include <stdio.h> #include <string.h> #include "gwnum/giants.h" #include "gwnum/gwnum.h" #include "gwnum/gwcommon.h" FILE *fd; char string[1000000]; int i, a = 0; // We want jacobi(a^2-4,n)==-1 unsigned long int LEN; unsigned long int para_a[1] = {0}, para_b[1] = {2}; // n == 3 (mod 4), b = a+2 unsigned long int init_s[1] = {1}, init_t[1] = {2}; giant n, p, s, t, z; // p = n+1 gwnum wn, wp, ws, wt, wx, wz; // wx, wz temps gwhandle *gwdata; int main ( int argc, char *argv[] ) { fd = fopen ( argv[1], "r" ); fscanf ( fd, "%s", string ); fclose ( fd ); LEN = strlen ( string ); LEN = ( LEN >> 2 ) + 8; n = newgiant ( LEN ); p = newgiant ( LEN ); s = newgiant ( LEN ); t = newgiant ( LEN ); z = newgiant ( LEN ); gwdata = (gwhandle*) malloc ( sizeof ( gwhandle ) ); gwinit (gwdata); ctog ( string, n ); gwsetup_general_mod_giant( gwdata, n ); wn = gwalloc ( gwdata ); wp = gwalloc ( gwdata ); ws = gwalloc ( gwdata ); wt = gwalloc ( gwdata ); wx = gwalloc ( gwdata ); wz = gwalloc ( gwdata ); itog ( 1, p ); addg ( n, p ); LEN = bitlen ( p ); binary64togw ( gwdata, init_s, 1, ws ); binary64togw ( gwdata, init_t, 1, wt ); for ( i = LEN-2; i >= 0; i-- ) { binary64togw ( gwdata, para_a, 1, wz ); gwsafemul ( gwdata, ws, wz ); gwaddquick ( gwdata, wt, wz ); gwaddquick ( gwdata, wt, wz ); gwsafemul ( gwdata, ws, wz ); gwsub3quick ( gwdata, wt, ws, wx ); gwaddquick ( gwdata, ws, wt ); gwsafemul ( gwdata, wx, wt ); gwcopy ( gwdata, wz, ws ); if ( bitval ( p, i ) ) { binary64togw ( gwdata, para_b, 1, wz ); gwsafemul ( gwdata, ws, wz ); gwaddquick ( gwdata, wt, wz ); gwaddquick ( gwdata, wt, wt ); gwsubquick ( gwdata, ws, wt ); gwcopy ( gwdata, wz, ws ); } } itog ( 2*a+5, z ); gwtogiant ( gwdata, wt, t ); subg ( z, t ); if ( gwiszero ( gwdata, ws ) && isZero ( t ) ) printf ( "Likely prime!\n" ); else printf ( "Not prime :(\n" ); } //gwtogiant( gwdata, ws, s ); //gtoc( s, string, 100 ); //printf( "%s\n", string ); //gcc s2.c gwnum/gwnum.a gwnum/gwnum.ld -lm -lpthread -lstdc++ //http://www.mersenneforum.org/showpost.php?p=388342&postcount=1 At the moment the program requires a number (==3 (mod 4)) to be in a file. Will I need to write my own jacobi() function? Last fiddled with by paulunderwood on 2015-09-07 at 05:51 |
![]() |
![]() |
![]() |
#5 | |
P90 years forever!
Aug 2002
Yeehaw, FL
41×193 Posts |
![]() Quote:
gwset_general_mod is the slowest way to use gwnum. gwnum does better testing numbers of the form k*b^n+c. My understanding is you are testing numbers where k=1, b=2, c=-3. The last in a series of gwadds or gwsubs should not be of the "quick" variety. Pull the binarytogw out of the loop, only do it once. Consider pre-FFTing the value (with gwfft) then use gwfftmul instead of gwsafemul. The last gwcopy to wz from ws seems pointless. |
|
![]() |
![]() |
![]() |
#6 | ||||
Sep 2002
Database er0rr
11·383 Posts |
![]() Quote:
Quote:
Quote:
Quote:
![]() Last fiddled with by paulunderwood on 2015-09-07 at 14:10 |
||||
![]() |
![]() |
![]() |
#7 |
P90 years forever!
Aug 2002
Yeehaw, FL
41·193 Posts |
![]()
If you do an addquick or subquick before a gwmul (or gwsafemul, gwsquare, etc.) then you may get a roundoff error in the multiplication.
|
![]() |
![]() |
![]() |
#8 | |
Sep 2002
Database er0rr
421310 Posts |
![]() Quote:
I found gwiszero() to be buggy. The new code for s2.c is: Code:
#include <stdio.h> #include <string.h> #include "gwnum/giants.h" #include "gwnum/gwnum.h" #include "gwnum/gwcommon.h" FILE *fd; char string[1000000]; float a = 0.0, b = 2.0; // We want minimum a: jacobi(a^2-4,n)==-1, b = a+2 int i, LEN; unsigned init_s[1] = {1}, init_t[1] = {2}; giant n, p, s, t, z; // p = n+1 gwnum ws, wt, wx, wz; // wx, wz temps gwhandle *gwdata; int main ( int argc, char *argv[] ) { fd = fopen ( argv[1], "r" ); fscanf ( fd, "%s", string ); fclose ( fd ); LEN = strlen ( string ); LEN = ( LEN >> 2 ) + 8; n = newgiant ( LEN ); p = newgiant ( LEN ); s = newgiant ( LEN ); t = newgiant ( LEN ); z = newgiant ( LEN ); gwdata = (gwhandle*) malloc (sizeof ( gwhandle ) ); gwinit ( gwdata ); ctog ( string, n ); gwsetup_general_mod_giant( gwdata, n ); ws = gwalloc ( gwdata ); wt = gwalloc ( gwdata ); wx = gwalloc ( gwdata ); wz = gwalloc ( gwdata ); binarytogw ( gwdata, init_s, 1, ws ); binarytogw ( gwdata, init_t, 1, wt ); itog ( 1, p ); addg ( n, p ); LEN = bitlen ( p ); for ( i = LEN-2; i >= 0; i-- ) { gwcopy ( gwdata, ws, wz ); gwsmallmul ( gwdata, a, wz ); gwaddquick ( gwdata, wt, wz ); gwadd ( gwdata, wt, wz ); gwsafemul ( gwdata, ws, wz ); gwsub3 ( gwdata, wt, ws, wx ); gwadd ( gwdata, ws, wt ); gwsafemul ( gwdata, wx, wt ); if ( bitval ( p, i ) ) { gwcopy ( gwdata, wz, wx ); gwsmallmul ( gwdata, b, wx ); gwadd ( gwdata, wt, wx ); gwaddquick ( gwdata, wt, wt ); gwsub ( gwdata, wz, wt ); gwcopy ( gwdata, wx, ws ); } else gwcopy ( gwdata, wz, ws ); } gwtogiant ( gwdata, ws, s ); gwtogiant ( gwdata, wt, t ); itog ( 2*(int)a+5, z ); subg ( t, z ); if ( isZero ( s ) && isZero ( z ) ) printf ( "Likely prime!\n" ); else printf ( "Not prime :(\n" ); } //gwtogiant( gwdata, ws, z ); //gtoc( z, string, 100 ); //printf( "s%s\n", string ); //gcc s2.c gwnum/gwnum.a gwnum/gwnum.ld -lm -lpthread -lstdc++ //http://www.mersenneforum.org/showpost.php?p=388342&postcount=1 Last fiddled with by paulunderwood on 2015-09-08 at 06:25 |
|
![]() |
![]() |
![]() |
#9 |
Sep 2002
Database er0rr
11×383 Posts |
![]()
I have changed the interface slightly; You now must enter the value of "a" -- minimal a: jacobi(a^2-4,n)==-1 -- on the command line. The interface is not important to this exercise. This is my final version.
I have re-written the main loop, getting rid of some gwcopy(). ![]() Code:
#include <stdio.h> #include <string.h> #include "gwnum/giants.h" #include "gwnum/gwnum.h" #include "gwnum/gwcommon.h" FILE *fd; char string[1000000]; float a , b; int i, LEN; unsigned init_s[1] = {1}, init_t[1] = {2}; giant n, p, s, t, z; // p = n+1 gwnum ws, wt, wx, wz; // wx, wz temps gwhandle *gwdata; int main ( int argc, char *argv[] ) { if( argc != 3 ) { printf( "Usage: s2 file_name a (where a is min: jacobi(a^2-4,n)==-1)\n" ); return; } fd = fopen ( argv[1], "r" ); fscanf ( fd, "%s", string ); fclose ( fd ); a = (float)atoi ( argv[2] ); b = a + 2.0; LEN = strlen ( string ); LEN = ( LEN >> 2 ) + 8; n = newgiant ( LEN ); p = newgiant ( LEN ); s = newgiant ( LEN ); t = newgiant ( LEN ); z = newgiant ( LEN ); gwdata = (gwhandle*) malloc (sizeof ( gwhandle ) ); gwinit ( gwdata ); ctog ( string, n ); gwsetup_general_mod_giant( gwdata, n ); ws = gwalloc ( gwdata ); wt = gwalloc ( gwdata ); wx = gwalloc ( gwdata ); wz = gwalloc ( gwdata ); binarytogw ( gwdata, init_s, 1, ws ); binarytogw ( gwdata, init_t, 1, wt ); itog ( 1, p ); addg ( n, p ); LEN = bitlen ( p ); gwcopy ( gwdata, ws, wz ); for ( i = LEN-2; i >= 0; i-- ) { gwcopy ( gwdata, wz, ws ); gwsmallmul ( gwdata, a, wz ); gwaddquick ( gwdata, wt, wz ); gwadd ( gwdata, wt, wz ); gwsafemul ( gwdata, ws, wz ); gwsub3 ( gwdata, wt, ws, wx ); gwadd ( gwdata, ws, wt ); gwsafemul ( gwdata, wx, wt ); if ( bitval ( p, i ) ) { gwcopy ( gwdata, wz, ws ); gwsmallmul ( gwdata, b, wz ); gwadd ( gwdata, wt, wz ); gwaddquick ( gwdata, wt, wt ); gwsubquick ( gwdata, ws, wt ); } } gwtogiant ( gwdata, wz, s ); gwtogiant ( gwdata, wt, t ); itog ( 2*(int)a+5, z ); subg ( t, z ); if ( isZero ( s ) && isZero ( z ) ) printf ( "Likely prime!\n" ); else printf ( "Not prime :(\n" ); } //gwtogiant( gwdata, ws, z ); //gtoc( z, string, 100 ); //printf( "s%s\n", string ); //gcc -o s2 s2.c gwnum/gwnum.a gwnum/gwnum.ld -lm -lpthread -lstdc++ //http://www.mersenneforum.org/showpost.php?p=388342&postcount=1 |
![]() |
![]() |
![]() |
#10 |
Sep 2002
Database er0rr
107516 Posts |
![]()
I added gwset_num_threads ( gwdata, 4 ); to the above program and ran it against this 971486-bit number. The percentage usage was heavily dependent on how many other tasks I was running. After killing a few, like Iceweasel, I noticed that the CPU usage went up to 255% of an idle 4770k (no HT). Can I expect more CPU usage from big mega-primes/PRPs? Here is the result (with some processes being killed throughout the run):
Code:
Likely prime! real 29m42.842s user 72m11.292s sys 2m36.888s Last fiddled with by paulunderwood on 2016-04-13 at 19:13 |
![]() |
![]() |
![]() |
#11 | |
Sep 2002
Database er0rr
10000011101012 Posts |
![]() Quote:
Code:
Likely prime! real 123m28.272s user 269m14.144s sys 7m14.316s ![]() |
|
![]() |
![]() |
![]() |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
LLR V3.8.2 using gwnum 26.2 is available! | Jean Penné | Software | 25 | 2010-11-01 15:18 |
GWNUM? | Unregistered | Information & Answers | 3 | 2010-09-12 19:52 |
GWNUM library and llr | leizhoucn | Programming | 2 | 2007-11-05 09:34 |
Compiling GMP-ECM With GWNUM | tmorrow | GMP-ECM | 5 | 2007-04-04 00:39 |
GWNUM as DLL? | Cyclamen Persicum | Software | 1 | 2007-01-02 20:53 |