# This is a perl script, invoked from a shell
use warnings; # this doesn't work on older versions of perl
sub GenConfigHeader {
my $line;
local *CFILE;
local *CFILEOUT;
open(CFILE, "< cfile");
open(CFILEOUT, "> cfileout");
while ($line = <CFILE>) {
$line =~ s/@\{(.*?)\}/$Config{$1}/ge;
print CFILEOUT $line;
}
close(CFILE);
close(CFILEOUT);
system("cp cfileout ../include/NTL/config.h");
}
sub RemoveProg {
# This should work on unix and cygwin on windows
my ($name) = @_;
unlink($name); unlink("$name.exe");
}
sub RunProg {
my ($name) = @_;
my $val;
my $res;
system("make wntl.a") and return "999999999999999";
RemoveProg($name);
system("make $name") and return "999999999999999";
print "\n*** running $name...";
$val = `./$name`;
if ($? != 0) {
$res = "999999999999999";
}
else {
($res) = ( $val =~ /^([0-9]*)/ );
}
print $val, "\n";
return $res;
}
############################################################
system("make InitSettings");
@lines = `./InitSettings`;
%Config = (
'NTL_LONG_LONG' => 0,
'NTL_AVOID_FLOAT' => 0,
'NTL_SPMM_ULL' => 0,
'NTL_SPMM_ASM' => 0,
'NTL_TBL_REM' => 0,
'NTL_TBL_REM_LL' => 0,
'NTL_CRT_ALTCODE' => 0,
'NTL_CRT_ALTCODE_SMALL'=> 0,
'NTL_AVOID_BRANCHING' => 0,
'NTL_GF2X_ALTCODE' => 0,
'NTL_GF2X_ALTCODE1' => 0,
'NTL_GF2X_NOINLINE' => 0,
'NTL_PCLMUL' => 0,
'NTL_FFT_BIGTAB' => 0,
'NTL_FFT_LAZYMUL' => 0,
'WIZARD_HACK' => '#define NTL_WIZARD_HACK',
);
foreach $line (@lines) {
chomp($line);
($name, $val) = ($line =~ /(.*?)=(.*)/);
$Config{$name} = $val;
}
# set AVOID_BRANCHING, SPMM, and FFT flags...try all combinations
$time = "999999999999999";
$aflag = "default";
$bflag = "default";
$cflag = "default";
$Config{"NTL_FFT_BIGTAB"} = 1;
foreach $aflag1 ("default", "NTL_FFT_LAZYMUL") {
foreach $bflag1 ("default", "NTL_SPMM_ULL", "NTL_SPMM_ASM") {
foreach $cflag1 ("default", "NTL_AVOID_BRANCHING") {
$Config{$aflag1} = 1;
$Config{$bflag1} = 1;
$Config{$cflag1} = 1;
if ($Config{"NTL_FFT_LAZYMUL"} == 1 && $Config{"NTL_LONGLONG_SP_MULMOD"} == 0 &&
$Config{"NTL_SPMM_ULL"} == 0 && $Config{"NTL_SPMM_ASM"} == 0) {
$Config{$aflag1} = 0;
$Config{$bflag1} = 0;
$Config{$cflag1} = 0;
print "skip: $aflag1 $bflag1 $cflag1\n";
next;
}
if ($Config{"NTL_LONGLONG_SP_MULMOD"} == 1 && $Config{"NTL_SPMM_ULL"} == 1) {
$Config{$aflag1} = 0;
$Config{$bflag1} = 0;
$Config{$cflag1} = 0;
print "skip: $aflag1 $bflag1 $cflag1\n";
next;
}
print "run: $aflag1 $bflag1 $cflag1 NTL_FFT_BIGTAB\n";
GenConfigHeader();
$time1 = RunProg("Poly1TimeTest");
if ($time1 < $time) {
$aflag = $aflag1;
$bflag = $bflag1;
$cflag = $cflag1;
$time = $time1;
}
$Config{$aflag1} = 0;
$Config{$bflag1} = 0;
$Config{$cflag1} = 0;
# these are the files that include class definitions
# from FFT.h and ZZ_p.h, which have memvers defined
# in terms of mulmod_precon_t
unlink("FFT.o"); unlink("ZZ_p.o"); unlink("vec_ZZ_p.o");
unlink("ZZ_pX.o"); unlink("ZZ_pX1.o");
}
}
}
$Config{$aflag} = 1;
$Config{$bflag} = 1;
$Config{$cflag} = 1;
# now see if BIGTAB really helps
$Config{"NTL_FFT_BIGTAB"} = 0;
print "run: $aflag $bflag $cflag default\n";
GenConfigHeader();
$time1 = RunProg("Poly1TimeTest");
if ($time1*1.0 > $time*1.04) {
# stick with BIGTABs
$Config{"NTL_FFT_BIGTAB"} = 1;
}
unlink("FFT.o"); unlink("ZZ_p.o"); unlink("vec_ZZ_p.o");
unlink("ZZ_pX.o"); unlink("ZZ_pX1.o");
# also unlink lip.o, since that may depend on the MulMod impl
unlink("lip.o");
# set flags NTL_GF2X_NOINLINE, NTL_GF2X_ALTCODE, NTL_GF2X_ALTCODE1
$time = "999999999999999";
$aflag = "default";
$bflag = "default";
foreach $aflag1 ("default", "NTL_GF2X_NOINLINE") {
foreach $bflag1 ("default", "NTL_GF2X_ALTCODE", "NTL_GF2X_ALTCODE1") {
$Config{$aflag1} = 1;
$Config{$bflag1} = 1;
GenConfigHeader();
$time1 = RunProg("GF2XTimeTest");
if ($time1 < $time) {
$aflag = $aflag1;
$bflag = $bflag1;
$time = $time1;
}
$Config{$aflag1} = 0;
$Config{$bflag1} = 0;
unlink("GF2X.o");
}
}
# now try NTL_PCLMUL instead
unlink("GF2X.o");
unlink("GF2X1.o");
$Config{"NTL_PCLMUL"} = 1;
GenConfigHeader();
$time1 = RunProg("GF2XTimeTest");
unlink("GF2X.o");
unlink("GF2X1.o");
if ($time1 >= $time) {
$Config{"NTL_PCLMUL"} = 0;
$Config{$aflag} = 1;
$Config{$bflag} = 1;
}
if ($Config{"NTL_GMP_LIP"} == 0) {
# GMP is not the primary long integer package
# Choose between default, AVOID_FLOAT, and LONG_LONG implementatsions
$time = "999999999999999";
$flag = "default";
foreach $flag1 ("default", "NTL_AVOID_FLOAT", "NTL_LONG_LONG") {
$Config{$flag1} = 1;
GenConfigHeader();
$time1 = RunProg("MulTimeTest");
if ($time1 < $time) {
$flag = $flag1;
$time = $time1;
}
$Config{$flag1} = 0;
unlink("lip.o");
}
$Config{$flag} = 1;
# finally, now set TBL_REM and TBL_REM_LL
$time = "999999999999999";
$flag = "default";
foreach $flag1 ("default", "NTL_TBL_REM", "NTL_TBL_REM_LL") {
$Config{$flag1} = 1;
GenConfigHeader();
$time1 = RunProg("Poly2TimeTest");
if ($time1 < $time) {
$flag = $flag1;
$time = $time1;
}
$Config{$flag1} = 0;
unlink("lip.o");
}
$Config{$flag} = 1;
}
else {
# set NTL_TBL_REM
$time = "999999999999999";
$flag = "default";
foreach $flag1 ("default", "NTL_TBL_REM") {
$Config{$flag1} = 1;
GenConfigHeader();
$time1 = RunProg("Poly2TimeTest");
if ($time1 < $time) {
$flag = $flag1;
$time = $time1;
}
$Config{$flag1} = 0;
unlink("lip.o");
}
$Config{$flag} = 1;
# set NTL_CRT_ALTCODE
$time = "999999999999999";
$flag = "default";
foreach $flag1 ("default", "NTL_CRT_ALTCODE") {
$Config{$flag1} = 1;
GenConfigHeader();
$time1 = RunProg("Poly3TimeTest");
if ($time1 < $time) {
$flag = $flag1;
$time = $time1;
}
$Config{$flag1} = 0;
unlink("lip.o");
}
$Config{$flag} = 1;
# set NTL_CRT_ALTCODE_SMALL, if NTL_CRT_ALTCODE
# not set but it did not perform too badly
if ($Config{"NTL_CRT_ALTCODE"} == 0) {
# time measures default and time1 measures ALTCODE
if (1.0*$time1 < 1.15*$time) {
$Config{"NTL_CRT_ALTCODE_SMALL"} = 1;
}
}
}
$Config{'WIZARD_HACK'} = "";
GenConfigHeader();
print "\n\n*** the wizard is done!!\n\n";
system("make DispSettings");
system("./DispSettings");
system("./DispSettings > wizard_log.h");