Skip to content

Commit 00a3351

Browse files
committed
Merge branch 'master' of github.com:linbox-team/linbox
2 parents 99db939 + 30970b7 commit 00a3351

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+4477
-1815
lines changed

benchmarks/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ PERFPUBLISHERFILE=benchmarks-report.xml
3939
BENCH_BASIC= \
4040
benchmark-example\
4141
benchmark-fft\
42+
benchmark-polynomial-matrix-mul-fft \
4243
benchmark-dense-solve\
4344
benchmark-order-basis \
4445
benchmark-solve-cra
@@ -97,6 +98,7 @@ benchmarks: ${EXTRA_PROGRAMS}
9798
benchmark_example_SOURCES = benchmark-example.C
9899
benchmark_order_basis_SOURCES = benchmark-order-basis.C
99100
benchmark_fft_SOURCES = benchmark-fft.C
101+
benchmark_polynomial_matrix_mul_fft_SOURCES = benchmark-polynomial-matrix-mul-fft.C
100102
benchmark_dense_solve_SOURCES = benchmark-dense-solve.C
101103
benchmark_solve_cra_SOURCES = benchmark-solve-cra.C
102104

benchmarks/benchmark-order-basis.C

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ bool operator==(const MatPol& A, const MatPol& B){
261261
template<typename Field, typename RandIter>
262262
void bench_sigma(const Field& F, RandIter& Gen, size_t m, size_t n, size_t d, string target) {
263263
//typedef typename Field::Element Element;
264-
//typedef PolynomialMatrix<PMType::matfirst,PMStorage::plain,Field> MatrixP;
265-
typedef PolynomialMatrix<PMType::polfirst,PMStorage::plain,Field> MatrixP;
264+
//typedef PolynomialMatrix<Field,PMType::matfirst> MatrixP;
265+
typedef PolynomialMatrix<Field,PMType::polfirst> MatrixP;
266266
std::cout<<"Order Basis computation over ";F.write(cout)<<endl;
267267
integer p;
268268
F.characteristic(p);
Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
/*
2+
* Copyright (C) 2020 Cyril Bouvier, Pascal Giorgi
3+
*
4+
* Written by Cyril Bouvier <[email protected]>
5+
* Pascal Giorgi <[email protected]>
6+
*
7+
* ========LICENCE========
8+
* This file is part of the library LinBox.
9+
*
10+
* LinBox is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU Lesser General Public
12+
* License as published by the Free Software Foundation; either
13+
* version 2.1 of the License, or (at your option) any later version.
14+
*
15+
* This library is distributed in the hope that it will be useful,
16+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18+
* Lesser General Public License for more details.
19+
*
20+
* You should have received a copy of the GNU Lesser General Public
21+
* License along with this library; if not, write to the Free Software
22+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23+
* ========LICENCE========
24+
*/
25+
26+
27+
28+
29+
#include <iostream>
30+
#include <iomanip>
31+
using namespace std;
32+
33+
//#define FFT_PROFILER
34+
#include <linbox/ring/modular.h>
35+
#include <linbox/randiter/random-prime.h>
36+
#include <linbox/randiter/random-fftprime.h>
37+
#include <givaro/zring.h>
38+
#include <recint/rint.h>
39+
#include <linbox/matrix/matrix-domain.h>
40+
#include <linbox/util/commentator.h>
41+
#include <linbox/util/timer.h>
42+
#include <linbox/matrix/polynomial-matrix.h>
43+
#include <linbox/algorithms/polynomial-matrix/polynomial-matrix-domain.h>
44+
#include <linbox/algorithms/polynomial-matrix/matpoly-mult-naive.h>
45+
#include <linbox/algorithms/polynomial-matrix/matpoly-mult-kara.h>
46+
47+
#include <givaro/modular.h>
48+
#include <givaro/modular-extended.h>
49+
#include <fflas-ffpack/utils/args-parser.h>
50+
51+
using namespace std;
52+
using namespace LinBox;
53+
using Givaro::Modular;
54+
using Givaro::ModularExtended;
55+
56+
/* For pretty printing type */
57+
template<typename ...> const char *TypeName();
58+
template<template <typename ...> class> const char *TypeName();
59+
60+
#define REGISTER_TYPE_NAME(type) \
61+
template<> const char *TypeName<type>(){return #type;}
62+
63+
REGISTER_TYPE_NAME(float);
64+
REGISTER_TYPE_NAME(double);
65+
REGISTER_TYPE_NAME(uint16_t);
66+
REGISTER_TYPE_NAME(uint32_t);
67+
REGISTER_TYPE_NAME(uint64_t);
68+
REGISTER_TYPE_NAME(uint128_t);
69+
REGISTER_TYPE_NAME(Modular);
70+
REGISTER_TYPE_NAME(ModularExtended);
71+
72+
73+
74+
using namespace LinBox;
75+
76+
77+
78+
template<typename PolMatType, typename PolMatMulDomain>
79+
double bench_one (const PolMatMulDomain &PMMD, unsigned int m, unsigned int n,
80+
unsigned int k, unsigned int d, unsigned long seed) {
81+
Timer chrono;
82+
size_t cnt;
83+
double time;
84+
typename PolMatType::Field::RandIter G(PMMD.field(), seed);
85+
86+
PolMatType M(PMMD.field(),m,n,d), N(PMMD.field(),n,k,d);
87+
PolMatType R(PMMD.field(),m,k,2*d-1);
88+
89+
M.random(G);
90+
N.random(G);
91+
92+
chrono.start();
93+
for (cnt = 0; chrono.realElapsedTime() < 1 ; cnt++)
94+
PMMD.mul (R, M, N);
95+
time = chrono.userElapsedTime()/cnt; /* time per iteration */
96+
97+
return time;
98+
}
99+
100+
/* Bench multiplication via FFT on polynomial matrices with coefficients in
101+
* ModImplem<Elt, C...> (i.e., Modular<Elt, C> or ModularExtended<Elt>) with a
102+
* random prime p with the required number of bits and such that 2^k divides p-1
103+
*/
104+
template<template<typename, typename...> class ModImplem, typename Elt, typename... C>
105+
void bench_one_modular_implem_fft (uint64_t bits, unsigned int m,
106+
unsigned int n, unsigned int k,
107+
unsigned int d, unsigned long seed)
108+
{
109+
typedef ModImplem<Elt, C...> Field;
110+
double time;
111+
112+
/* First, we check if this Modular implem can handle this many bits */
113+
bool ok;
114+
typename Field::Residu_t s = 1;
115+
for (uint64_t i = 0; i+1 < bits; i++, s<<=1); /* at the end s=2^(bits-1) */
116+
if (s == 0)
117+
ok = false;
118+
else {
119+
s <<= 1; s--; /* now s=2^bits-1 */
120+
ok = (s <= Field::maxCardinality());
121+
}
122+
if (!ok) {
123+
cout << endl << "# Skipping bench with " << TypeName<ModImplem>();
124+
cout << "<" << TypeName<Elt>();
125+
if (sizeof...(C) > 0)
126+
cout << ", " << TypeName<C...>();
127+
cout << ">, bits = " << bits << " is too large" << endl;
128+
return;
129+
}
130+
131+
size_t lpts = 0;
132+
size_t pts = 1; while (pts <= 2*d-2) { pts<<=1; lpts++; }
133+
integer p;
134+
RandomFFTPrime::seeding (seed);
135+
if (!RandomFFTPrime::randomPrime (p, integer(1)<<bits, lpts)) {
136+
cout << endl << "# Skipping bench with " << TypeName<ModImplem>();
137+
cout << "<" << TypeName<Elt>();
138+
if (sizeof...(C) > 0)
139+
cout << ", " << TypeName<C...>();
140+
cout << ">, RandomFFTPrime::randomPrime failed to find a prime" << endl;
141+
return;
142+
}
143+
Field GFp ((Elt) p);
144+
145+
cout << endl << string (80, '*') << endl;
146+
cout << "Bench polynomial matrix multiplication with "
147+
<< TypeName<ModImplem>() << "<" <<TypeName<Elt>();
148+
if (sizeof...(C) > 0)
149+
cout << ", " << TypeName<C...>();
150+
cout << ">, p=" << GFp.cardinality() << " (" << bits << " bits, ";
151+
cout << "n=2^" << k << " divides p-1)" << endl;
152+
153+
typedef PolynomialMatrixFFTPrimeMulDomain<Field> PMMDType;
154+
PMMDType PMMD_fft (GFp);
155+
156+
typedef PolynomialMatrix<Field, PMType::polfirst> MatrixP;
157+
typedef PolynomialMatrix<Field, PMType::matfirst> PMatrix;
158+
typedef PolynomialMatrix<Field, PMType::matrowfirst> PMatrixP;
159+
160+
/* polfirst */
161+
time = bench_one<MatrixP> (PMMD_fft, m, n, k, d, seed);
162+
cout << " polfirst " << string (80-25, ' ');
163+
cout.precision(2); cout.width(10); cout<< scientific << time << " s";
164+
cout << endl;
165+
166+
/* matfirst */
167+
time = bench_one<PMatrix> (PMMD_fft, m, n, k, d, seed);
168+
cout << " matfirst " << string (80-25, ' ');
169+
cout.precision(2); cout.width(10); cout<< scientific << time << " s";
170+
cout << endl;
171+
172+
/* matrowfirst */
173+
/* TODO: does not compile */
174+
time = bench_one<PMatrixP> (PMMD_fft, m, n, k, d, seed);
175+
cout << " matrowfirst " << string (80-25-3, ' ');
176+
cout.precision(2); cout.width(10); cout<< scientific << time << " s";
177+
cout << endl;
178+
}
179+
180+
/******************************************************************************/
181+
/************************************ main ************************************/
182+
/******************************************************************************/
183+
int main (int argc, char* argv[]) {
184+
unsigned long bits = 23;
185+
unsigned long seed = time (NULL);
186+
unsigned long m = 10;
187+
unsigned long n = 30;
188+
unsigned long k = 20;
189+
unsigned long d = 2000;
190+
191+
Argument args[] = {
192+
{ 'b', "-b nbits", "number of bits of prime.", TYPE_INT, &bits },
193+
{ 'm', "-m m", "number of rows of first matrix.", TYPE_INT, &m },
194+
{ 'n', "-n n", "number of columns of first matrix and rows of second matrix.", TYPE_INT, &n },
195+
{ 'k', "-k k", "number of columns of second matrix.", TYPE_INT, &k },
196+
{ 'd', "-d d", "strict bound on degree of matrices.", TYPE_INT, &d },
197+
{ 's', "-s seed", "set the seed.", TYPE_INT, &seed },
198+
END_OF_ARGUMENTS
199+
};
200+
201+
parseArguments (argc, argv, args);
202+
203+
cout << "# command: ";
204+
FFLAS::writeCommandString (cout, args, "benchmark-polynomial-matrix-mul-fft") << endl;
205+
206+
if (d >> (bits-1)) {
207+
cerr << "Error, d=" << d << " must be smaller than 2^nbits-1";
208+
cerr << endl;
209+
return 1;
210+
}
211+
212+
/* Bench with Modular<float, double> */
213+
bench_one_modular_implem_fft<Modular, float, double> (bits, m, n, k, d, seed);
214+
215+
/* Bench with Modular<double, double> */
216+
bench_one_modular_implem_fft<Modular, double> (bits, m, n, k, d, seed);
217+
218+
/* Bench with ModularExtended<double> */
219+
/* TODO: does not compile */
220+
//bench_one_modular_implem_fft<ModularExtended, double> (bits, m, n, k, d, seed);
221+
222+
/* Bench with Modular<uint16_t,uint32_t> */
223+
bench_one_modular_implem_fft<Modular, uint16_t, uint32_t> (bits, m, n, k, d, seed);
224+
225+
/* Bench with Modular<uint32_t> */
226+
bench_one_modular_implem_fft<Modular, uint32_t> (bits, m, n, k, d, seed);
227+
228+
/* Bench with Modular<uint32_t, uint64_t> */
229+
bench_one_modular_implem_fft<Modular, uint32_t, uint64_t> (bits, m, n, k, d, seed);
230+
231+
/* Bench with Modular<uint64_t> */
232+
bench_one_modular_implem_fft<Modular, uint64_t> (bits, m, n, k, d, seed);
233+
234+
#ifdef __FFLASFFPACK_HAVE_INT128
235+
/* Bench with Modular<uint64_t,uint128_t> */
236+
bench_one_modular_implem_fft<Modular, uint64_t, uint128_t> (bits, m, n, k, d, seed);
237+
#endif
238+
239+
return 0;
240+
}
241+
242+
// Local Variables:
243+
// mode: C++
244+
// tab-width: 4
245+
// indent-tabs-mode: nil
246+
// c-basic-offset: 4
247+
// End:
248+
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s

linbox/algorithms/blackbox-block-container-base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class BlackboxBlockContainerBase {
106106

107107
// Sequence constructor from a blackbox and a field
108108
// cs set the size of the sequence
109-
BlackboxBlockContainerBase (const Blackbox *BD, const Field &F, size_t m, size_t n, size_t seed=(size_t)time(NULL)) :
109+
BlackboxBlockContainerBase (const Blackbox *BD, const Field &F, size_t m, size_t n, size_t seed=static_cast<size_t>(std::time(nullptr))) :
110110
_field(&F) , _BB(BD), _size(std::max(BD->rowdim()/m,size_t(1)) + std::max(BD->coldim()/n,size_t(1)) +__BW_EXTRA_STEPS)
111111
, _nn(BD->rowdim()), _m(m), _n(n)
112112
,casenumber(0)

linbox/algorithms/blackbox-block-container.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ namespace LinBox
9494
}
9595

9696
// constructor of the sequence from a blackbox, a field and two blocks random projection
97-
BlackboxBlockContainer(const _Blackbox *D, const Field &F, size_t m, size_t n, size_t seed= (size_t)time(NULL)) :
97+
BlackboxBlockContainer(const _Blackbox *D, const Field &F, size_t m, size_t n, size_t seed= static_cast<size_t>(std::time(nullptr))) :
9898
BlackboxBlockContainerBase<Field, _Blackbox, _MatrixDomain> (D, F, m, n,seed)
9999
, _blockW(F,D->rowdim(), n), _BMD(F)
100100
{
@@ -233,7 +233,7 @@ namespace LinBox
233233
}
234234

235235
// constructor of the sequence from a blackbox, a field and two blocks random projection
236-
BlackboxBlockContainerRecord(const _Blackbox *D, const Field &F, size_t m, size_t n, size_t seed= (size_t)time(NULL)) :
236+
BlackboxBlockContainerRecord(const _Blackbox *D, const Field &F, size_t m, size_t n, size_t seed= static_cast<size_t>(std::time(nullptr))) :
237237
BlackboxBlockContainerBase<Field, _Blackbox, _MatrixDomain> (D, F, m, n,seed),
238238
_blockW(D->rowdim(), n), _BMD(F), _launcher(Nothing), _iter(1)
239239
{

linbox/algorithms/block-massey-domain.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ namespace LinBox
578578

579579
// Make the Power Serie from Sequence (U.A^i.V) and Identity
580580
//_container->recompute(); // make sure sequence is already computed
581-
typedef PolynomialMatrix<PMType::polfirst,PMStorage::plain, Field> PMatrix;
581+
typedef PolynomialMatrix<Field, PMType::polfirst> PMatrix;
582582
PMatrix PowerSerie(field(),mn,n,length);
583583

584584
typename Sequence::const_iterator _iter (_container->begin ());
@@ -620,15 +620,16 @@ namespace LinBox
620620
}
621621

622622
// convert to polynomial of matrices
623-
PolynomialMatrix<PMType::matfirst,PMStorage::plain, Field> Sigma (field(), mn,mn,SigmaBase.size());
623+
PolynomialMatrix<Field, PMType::matfirst> Sigma (field(), mn,mn,SigmaBase.size());
624624
Sigma.copy(SigmaBase);
625625

626626
BlasPermutation<size_t> BPerm(Perm);
627627

628628
// Apply BPerm to the Sigma Base
629-
for (size_t i=0;i<Sigma.size();++i)
630-
_BMD.mulin_right(BPerm,Sigma[i]);
631-
629+
for (size_t i=0;i<Sigma.size();++i){
630+
auto Sigmai=Sigma[i];
631+
_BMD.mulin_right(BPerm,Sigmai);
632+
}
632633

633634

634635
#ifdef __PRINT_SIGMABASE

linbox/algorithms/matpoly-mult.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ namespace LinBox
986986
// find a pseudo primitive element of the multiplicative group _p -1
987987
long m = _pl - 1;
988988
long k = 0;
989-
srand((unsigned int)time(NULL));
989+
srand(static_cast<unsigned int>(std::time(nullptr)));
990990
while ((m & 1) == 0) {
991991
m = m >> 1;
992992
k++;
@@ -1049,7 +1049,7 @@ namespace LinBox
10491049
// find a pseudo primitive element of the multiplicative group _p-1
10501050
long mm = _pl - 1;
10511051
long kk = 0;
1052-
srand((unsigned int)time(NULL));
1052+
srand(static_cast<unsigned int>(std::time(nullptr)));
10531053
while ((mm & 1) == 0) {
10541054
mm = mm >> 1;
10551055
kk++;
@@ -1271,7 +1271,7 @@ namespace LinBox
12711271
// find a pseudo primitive element of the multiplicative group _p-1
12721272
long mm = _pl - 1;
12731273
long kk = 0;
1274-
srand((unsigned int)time(NULL));
1274+
srand(static_cast<unsigned int>(std::time(nullptr)));
12751275
while ((mm & 1) == 0) {
12761276
mm = mm >> 1;
12771277
kk++;
@@ -1430,7 +1430,7 @@ namespace LinBox
14301430
// find a pseudo primitive element of the multiplicative group _p-1
14311431
long mm = _pl - 1;
14321432
long kk = 0;
1433-
srand((unsigned int)time(NULL));
1433+
srand(static_cast<unsigned int>(std::time(nullptr)));
14341434
while ((mm & 1) == 0) {
14351435
mm = mm >> 1;
14361436
kk++;

0 commit comments

Comments
 (0)