1 /*
2  * Copyright (C) FFLAS-FFPACK
3  * Written by Pascal Giorgi <pascal.giorgi@lirmm.fr>
4  * and Clement Pernet <clement.pernet@univ-grenoble-alpes.fr>
5  * This file is Free Software and part of FFLAS-FFPACK.
6  *
7  * ========LICENCE========
8  * This file is part of the library FFLAS-FFPACK.
9  *
10  * FFLAS-FFPACK 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 #define  __FFLASFFPACK_SEQUENTIAL
27 
28 #define ENABLE_ALL_CHECKINGS 1
29 
30 #include "fflas-ffpack/fflas-ffpack-config.h"
31 
32 #include <iomanip>
33 #include <iostream>
34 #include <random>
35 
36 #include "fflas-ffpack/utils/timer.h"
37 #include "fflas-ffpack/fflas/fflas.h"
38 #include "fflas-ffpack/utils/args-parser.h"
39 #include "fflas-ffpack/utils/test-utils.h"
40 #include <givaro/modular.h>
41 
42 using namespace std;
43 using namespace FFPACK;
44 using namespace FFLAS;
45 using Givaro::Modular;
46 using Givaro::ModularBalanced;
47 
48 
49 template<typename Field, class RandIter>
check_ftrsv(const Field & F,size_t n,FFLAS_UPLO uplo,FFLAS_TRANSPOSE trans,FFLAS_DIAG diag,RandIter & Rand)50 bool check_ftrsv (const Field &F, size_t n, FFLAS_UPLO uplo, FFLAS_TRANSPOSE trans, FFLAS_DIAG diag, RandIter& Rand){
51 
52     typedef typename Field::Element Element;
53     Element * A, *b, *b2, *c;
54     size_t lda = n + (rand() % n );
55     size_t incb = 1 + (rand() % 2);
56     A  = fflas_new(F,n,lda);
57     b  = fflas_new(F,n,incb);
58     b2 = fflas_new(F,n,incb);
59     c  = fflas_new(F,n,incb);
60 
61     RandomTriangularMatrix (F, n, n, uplo, diag, true, A, lda, Rand);
62     RandomMatrix (F, n, incb, b, incb, Rand);
63     fassign (F, n, incb, b, incb, b2, incb);
64 
65     string ss=string((uplo == FflasLower)?"Lower_":"Upper_")+string((trans == FflasTrans)?"Trans_":"NoTrans_")+string((diag == FflasUnit)?"Unit":"NonUnit");
66 
67     cout<<std::left<<"Checking FTRSV_";
68     cout.fill('.');
69     cout.width(30);
70     cout<<ss;
71 
72 
73     Timer t; t.clear();
74     double time=0.0;
75     t.clear();
76     t.start();
77     ftrsv (F, uplo, trans, diag, n, A, lda, b, incb);
78     t.stop();
79     time+=t.usertime();
80 
81     fgemv(F, trans, n, n, F.one, A, lda, b, incb, F.zero, c, incb);
82 
83     bool ok = true;
84     if (fequal (F, n,  b2, incb, c, incb)){
85         //cout << "\033[1;32mPASSED\033[0m ("<<time<<")"<<endl;
86         cout << "PASSED ("<<time<<")"<<endl;
87         //cerr<<"PASSED ("<<time<<")"<<endl;
88     } else{
89         //cout << "\033[1;31mFAILED\033[0m ("<<time<<")"<<endl;
90         cout << "FAILED ("<<time<<")"<<endl;
91         ok=false;
92         //cerr<<"FAILED ("<<time<<")"<<endl;
93     }
94 
95     fflas_delete(A);
96     fflas_delete(b);
97     fflas_delete(b2);
98     fflas_delete(c);
99     return ok;
100 }
101 template <class Field>
run_with_field(Givaro::Integer q,size_t b,size_t n,size_t iters,uint64_t seed)102 bool run_with_field (Givaro::Integer q, size_t b, size_t n, size_t iters, uint64_t seed){
103     bool ok = true ;
104     int nbit=(int)iters;
105 
106     while (ok &&  nbit){
107         //typedef typename Field::Element Element ;
108         // choose Field
109         Field* F= chooseField<Field>(q,b,seed);
110         typename Field::RandIter G(*F,0,seed++);
111         if (F==nullptr)
112             return true;
113 
114         cout<<"Checking with ";F->write(cout)<<endl;
115 
116         ok = ok && check_ftrsv(*F,n,FflasLower,FflasNoTrans,FflasUnit,G);
117         ok = ok && check_ftrsv(*F,n,FflasUpper,FflasNoTrans,FflasUnit,G);
118         ok = ok && check_ftrsv(*F,n,FflasLower,FflasTrans,FflasUnit,G);
119         ok = ok && check_ftrsv(*F,n,FflasUpper,FflasTrans,FflasUnit,G);
120         ok = ok && check_ftrsv(*F,n,FflasLower,FflasNoTrans,FflasNonUnit,G);
121         ok = ok && check_ftrsv(*F,n,FflasUpper,FflasNoTrans,FflasNonUnit,G);
122         ok = ok && check_ftrsv(*F,n,FflasLower,FflasTrans,FflasNonUnit,G);
123         ok = ok && check_ftrsv(*F,n,FflasUpper,FflasTrans,FflasNonUnit,G);
124         nbit--;
125         delete F;
126     }
127     return ok;
128 }
129 
main(int argc,char ** argv)130 int main(int argc, char** argv)
131 {
132     cerr<<setprecision(10);
133     Givaro::Integer q=-1;
134     size_t b=0;
135     size_t n=483;
136     size_t iters=1;
137     bool loop=false;
138     uint64_t seed = getSeed();
139     Argument as[] = {
140         { 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INTEGER , &q },
141         { 'b', "-b B", "Set the bitsize of the field characteristic.",  TYPE_INT , &b },
142         { 'n', "-n N", "Set the dimension of the system.", TYPE_INT , &n },
143         { 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iters },
144         { 'l', "-loop Y/N", "run the test in an infinite loop.", TYPE_BOOL , &loop },
145         { 's', "-s seed", "Set seed for the random generator", TYPE_UINT64, &seed },
146         END_OF_ARGUMENTS
147     };
148 
149     parseArguments(argc,argv,as);
150 
151     bool ok = true;
152     do{
153         ok = ok && run_with_field<Modular<double> >(q,b,n,iters,seed);
154         ok = ok && run_with_field<ModularBalanced<double> >(q,b,n,iters,seed);
155         ok = ok && run_with_field<Modular<float> >(q,b,n,iters,seed);
156         ok = ok && run_with_field<ModularBalanced<float> >(q,b,n,iters,seed);
157         ok = ok && run_with_field<Modular<int32_t> >(q,b,n,iters,seed);
158         ok = ok && run_with_field<ModularBalanced<int32_t> >(q,b,n,iters,seed);
159         ok = ok && run_with_field<Modular<int64_t> >(q,b,n,iters,seed);
160         ok = ok && run_with_field<ModularBalanced<int64_t> >(q,b,n,iters,seed);
161         ok = ok && run_with_field<Modular<Givaro::Integer> >(q,5,n/4+1,iters,seed);
162         ok = ok && run_with_field<Modular<Givaro::Integer> >(q,(b?b:512),n/4+1,iters,seed);
163     } while (loop && ok);
164 
165     return !ok ;
166 }
167 /* -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
168 // vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
169