Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 93 additions & 92 deletions benchmarks/benchmark-fgemm.C
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ int main(int argc, char** argv) {
// typedef Givaro::Modular<Givaro::Integer> Field;
// typedef Givaro::Modular<int64_t> Field;
typedef Givaro::Modular<double> Field;
// typedef Givaro::ModularExtended<double> Field;
// typedef Givaro::Modular<float> Field;
// typedef Givaro::ModularBalanced<float> Field;
// typedef Givaro::ModularBalanced<double> Field;
Expand Down Expand Up @@ -115,95 +116,95 @@ int main(int argc, char** argv) {
for (size_t i=0;i<=iter;++i){

chrono.clear();
if (p && p!=7){
// CuttingStrategy meth = RECURSIVE;
// StrategyParameter strat = THREADS;

typedef CuttingStrategy::Block block;
typedef CuttingStrategy::Recursive rec;
typedef StrategyParameter::Threads threads;
typedef StrategyParameter::TwoD twod;
typedef StrategyParameter::TwoDAdaptive twoda;
typedef StrategyParameter::ThreeD threed;
typedef StrategyParameter::ThreeDAdaptive threeda;
typedef StrategyParameter::ThreeDInPlace threedip;
PAR_BLOCK{
if (i) { chrono.start(); }

switch (p){
case 1:{
MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<block,threads> > WH(F,nbw, SPLITTER(t,block,threads));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
break;}
case 2:{
MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,twod> > WH(F,nbw, SPLITTER(t,rec,twod));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
break;
}
case 3:{
MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,twoda> > WH(F,nbw, SPLITTER(t,rec,twoda));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
break;
}
case 4:{
MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,threedip> > WH(F,nbw, SPLITTER(t,rec,threedip));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
break;
}
case 5:{
MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,threed> > WH(F,nbw, SPLITTER(t,rec,threed));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
break;
}
case 6:{
MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,threeda> > WH(F,nbw, SPLITTER(t,rec,threeda));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
break;
}
default:{
MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<block,threads> > WH(F,nbw, SPLITTER(t,block,threads));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
break;
}
}
}
if (i) {chrono.stop(); time[i-1]=chrono.realtime();}
}else{
if(p==7){

int nrec = 0;
int dim = m;
// if(dim < 19000)
nrec--;
while(dim >= __FFLASFFPACK_WINOTHRESHOLD*2){
dim=dim/2;
nrec++;
}
nrec=std::max(1,nrec);
// std::cout<<" WINO_THREShold"<<__FFLASFFPACK_WINOTHRESHOLD<<" nrec = "<<nrec<<" dim = "<<dim<<std::endl;
if(nbw != -1)
nrec=nbw;
nbw=nrec;
if (i) chrono.start();
PAR_BLOCK
{
MMHelper<Field, MMHelperAlgo::WinogradPar,ModeTraits<Field>::value,ParSeqHelper::Parallel<> > WH (F, nrec, ParSeqHelper::Parallel<>(t));
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
}
if (i) {chrono.stop(); time[i-1]=chrono.realtime();}


// MMHelper<Field, MMHelperAlgo::WinogradPar>
// WH (F, nbw, ParSeqHelper::Sequential());
// // cout<<"wino parallel"<<endl;
// if (i) chrono.start();
// PAR_BLOCK
// {
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
// }
// if (i) {chrono.stop(); time+=chrono.realtime();}
}
else{
// if (p && p!=7){
// // CuttingStrategy meth = RECURSIVE;
// // StrategyParameter strat = THREADS;

// typedef CuttingStrategy::Block block;
// typedef CuttingStrategy::Recursive rec;
// typedef StrategyParameter::Threads threads;
// typedef StrategyParameter::TwoD twod;
// typedef StrategyParameter::TwoDAdaptive twoda;
// typedef StrategyParameter::ThreeD threed;
// typedef StrategyParameter::ThreeDAdaptive threeda;
// typedef StrategyParameter::ThreeDInPlace threedip;
// PAR_BLOCK{
// if (i) { chrono.start(); }

// switch (p){
// case 1:{
// MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<block,threads> > WH(F,nbw, SPLITTER(t,block,threads));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
// break;}
// case 2:{
// MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,twod> > WH(F,nbw, SPLITTER(t,rec,twod));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
// break;
// }
// case 3:{
// MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,twoda> > WH(F,nbw, SPLITTER(t,rec,twoda));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
// break;
// }
// case 4:{
// MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,threedip> > WH(F,nbw, SPLITTER(t,rec,threedip));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
// break;
// }
// case 5:{
// MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,threed> > WH(F,nbw, SPLITTER(t,rec,threed));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
// break;
// }
// case 6:{
// MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<rec,threeda> > WH(F,nbw, SPLITTER(t,rec,threeda));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
// break;
// }
// default:{
// MMHelper<Field, MMHelperAlgo::Winograd, typename ModeTraits<Field>::value, ParSeqHelper::Parallel<block,threads> > WH(F,nbw, SPLITTER(t,block,threads));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n, WH);
// break;
// }
// }
// }
// if (i) {chrono.stop(); time[i-1]=chrono.realtime();}
// }else{
// if(p==7){

// int nrec = 0;
// int dim = m;
// // if(dim < 19000)
// nrec--;
// while(dim >= __FFLASFFPACK_WINOTHRESHOLD*2){
// dim=dim/2;
// nrec++;
// }
// nrec=std::max(1,nrec);
// // std::cout<<" WINO_THREShold"<<__FFLASFFPACK_WINOTHRESHOLD<<" nrec = "<<nrec<<" dim = "<<dim<<std::endl;
// if(nbw != -1)
// nrec=nbw;
// nbw=nrec;
// if (i) chrono.start();
// PAR_BLOCK
// {
// MMHelper<Field, MMHelperAlgo::WinogradPar,ModeTraits<Field>::value,ParSeqHelper::Parallel<> > WH (F, nrec, ParSeqHelper::Parallel<>(t));
// fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
// }
// if (i) {chrono.stop(); time[i-1]=chrono.realtime();}


// // MMHelper<Field, MMHelperAlgo::WinogradPar>
// // WH (F, nbw, ParSeqHelper::Sequential());
// // // cout<<"wino parallel"<<endl;
// // if (i) chrono.start();
// // PAR_BLOCK
// // {
// // fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
// // }
// // if (i) {chrono.stop(); time+=chrono.realtime();}
// }
// else{

MMHelper<Field,MMHelperAlgo::Winograd>//,
//typename FieldTraits<Field>::value,
Expand All @@ -212,10 +213,10 @@ int main(int argc, char** argv) {
if (i) chrono.start();
fgemm (F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
if (i) {chrono.stop(); time[i-1]=chrono.realtime();}
}
}
//}


TimFreivalds.clear();
TimFreivalds.clear();
TimFreivalds.start();

bool pass = freivalds(F, FflasNoTrans, FflasNoTrans, m,n,k, F.one, A, k, B, n, C,n);
Expand Down
37 changes: 21 additions & 16 deletions fflas-ffpack/fflas/fflas_fadd.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,11 @@ namespace FFLAS {

// C = A + a B
template <class Field>
void
fadd (const Field& F, const size_t N,
typename Field::ConstElement_ptr A, const size_t inca,
const typename Field::Element alpha,
typename Field::ConstElement_ptr B, const size_t incb,
typename Field::Element_ptr C, const size_t incc)
void fadd (const Field& F, const size_t N,
typename Field::ConstElement_ptr A, const size_t inca,
const typename Field::Element alpha,
typename Field::ConstElement_ptr B, const size_t incb,
typename Field::Element_ptr C, const size_t incc)
{
if (C == A && inca == incc)
return faxpy(F,N,alpha,B,incb,C,incc);
Expand All @@ -125,9 +124,10 @@ namespace FFLAS {

if (inca == 1 && incb == 1 && incc == 1) {
for (size_t i = 0 ; i < N ; ++i) {
//!@todo optimise here
F.mul(C[i],alpha,B[i]);
F.addin(C[i],A[i]);
//!@todo optimise here
F.axpy (C[i], alpha, B[i], A[i]);
// F.mul(C[i],alpha,B[i]);
// F.addin(C[i],A[i]);
}
return;
}
Expand Down Expand Up @@ -302,21 +302,26 @@ namespace FFLAS {
return faxpy(F,M,N,alpha,B,ldb,C,ldc);
if (F.isOne(alpha))
return fadd(F,M,N,A,lda,B,ldb,C,ldc);
if (F.isMOne(alpha))
if (F.isMOne(alpha)){
return fsub(F,M,N,A,lda,B,ldb,C,ldc);
}
if (F.isZero(alpha))
return fassign(F,M,N,A,lda,C,ldc);

if (N == lda && N == ldb && N == ldc)
return fadd(F,M*N,A,1,alpha,B,1,C,1);

//TODO: use level 1 row by row when lda!=n
typename Field::ConstElement_ptr Ai = A, Bi = B;
typename Field::Element_ptr Ci = C;
for (; Ai < A+M*lda; Ai+=lda, Bi+=ldb, Ci+=ldc)
for (size_t i=0; i<N; i++) {
F.mul(Ci[i],alpha,Bi[i]);
F.addin (Ci[i], Ai[i]);
}
for (size_t i =0; i<M; ++i, Ai+=lda, Bi+=ldb, Ci+=ldc)
fadd (F, N, Ai, 1, alpha, Bi, 1, Ci, 1);
// typename Field::ConstElement_ptr Ai = A, Bi = B;
// typename Field::Element_ptr Ci = C;
// for (; Ai < A+M*lda; Ai+=lda, Bi+=ldb, Ci+=ldc)
// for (size_t i=0; i<N; i++) {
// F.mul(Ci[i],alpha,Bi[i]);
// F.addin (Ci[i], Ai[i]);
// }
}


Expand Down
32 changes: 24 additions & 8 deletions fflas-ffpack/fflas/fflas_fgemm.inl
Original file line number Diff line number Diff line change
Expand Up @@ -158,37 +158,53 @@ namespace FFLAS{ namespace Protected{
return false;
}

//Probable bug here due to overflow of int64_t
//Probable bug here due to overflow of int64_t
// returns 0 if no reduction need to be applied
// 1 if Op1 (P5) only need to be reduced
// 2 if beta*Op2 need to be reduced (for e.g. ModularExtended
template<class Field, class Element, class AlgoT, class ParSeqTrait>
inline bool NeedDoublePreAddReduction (Element& Outmin, Element& Outmax,
inline int NeedDoublePreAddReduction (Element& Outmin, Element& Outmax,
Element& Op1min, Element& Op1max,
Element& Op2min, Element& Op2max, Element beta,
MMHelper<Field, AlgoT, ModeCategories::LazyTag, ParSeqTrait >& WH)
{
// Testing if P5 need to be reduced
Outmin = std::min(beta*Op2min,beta*Op2max);
Outmax = std::max(beta*Op2min,beta*Op2max);
if (Op1max > WH.MaxStorableValue-Outmax ||
-Op1min > WH.MaxStorableValue+Outmin){
// std::cerr<<Op2min<<" < Op2 < "<<Op2max<<std::endl;
// std::cerr<<Outmin<<" < Out < "<<Outmax<<" beta = "<<beta<<std::endl;
// std::cerr<<"NeedDouble: Op1max = "<< Op1max<<" >? "<< WH.MaxStorableValue <<" - "<<Outmax<<" ="<<WH.MaxStorableValue-Outmax<<std::endl;
// std::cerr<<" -Op1min = "<< -Op1min<<" >? "<< WH.MaxStorableValue <<" + "<<Outmin<<" ="<<WH.MaxStorableValue+Outmin<<std::endl;
// std::cerr<<"OP1 = "<<Op1min<<" "<<Op1max<<std::endl;
if (Op1max > WH.MaxStorableValue-Outmax || -Op1min > WH.MaxStorableValue+Outmin){
Outmin += WH.FieldMin;
Outmax += WH.FieldMax;
return true;
return 1;
} else{
Outmin += Op1min;
Outmax += Op1max;
return false;
return 0;
}
}

template<class Field, class Element, class AlgoT, class ModeT, class ParSeqTrait>
inline bool NeedDoublePreAddReduction (Element& Outmin, Element& Outmax,
inline int NeedDoublePreAddReduction (Element& Outmin, Element& Outmax,
Element& Op1min, Element& Op1max,
Element& Op2min, Element& Op2max, Element beta,
MMHelper<Field, AlgoT, ModeT, ParSeqTrait>& WH)
{
Outmin = WH.FieldMin;
Outmax = WH.FieldMax;
return false;
return 0;
}
template<class Element, class AlgoT, class ParSeqTrait>
inline int NeedDoublePreAddReduction (Element& Outmin, Element& Outmax,
Element& Op1min, Element& Op1max,
Element& Op2min, Element& Op2max, Element beta,
MMHelper<Givaro::ModularExtended<Element>, AlgoT, ModeCategories::LazyTag, ParSeqTrait >& WH){
Outmin = WH.FieldMin;
Outmax = WH.FieldMax;
return 2;
}

template <class Field, class AlgoT, class ParSeqTrait>
Expand Down
8 changes: 5 additions & 3 deletions fflas-ffpack/fflas/fflas_fgemm/fgemm_classical.inl
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ namespace FFLAS {
if (F.isMOne(betadf)) betadf = -F.one;

size_t kmax = H.MaxDelayedDim (betadf);

H.checkA(F,ta, m,k,A,lda);
H.checkB(F,tb, k,n,B,ldb);
if (kmax <= k/2 || H.Aunfit() || H.Bunfit() ){
if (kmax <= k/2 || H.Aunfit() || H.Bunfit() ){ // TODO: K/2 may be too big
// Might as well reduce inputs
if (H.Amin < H.FieldMin || H.Amax>H.FieldMax){
H.initA();
Expand Down Expand Up @@ -207,8 +208,9 @@ namespace FFLAS {
if (tb == FflasNoTrans)
for (size_t i = 0; i < m; ++i)
for (size_t l = 0; l < k; ++l)
for (size_t j = 0; j < n; ++j)
F.axpyin (*(C+i*ldc+j), *(A+i*lda+l), *(B+l*ldb+j));
for (size_t j = 0; j < n; ++j) {
F.axpyin (*(C+i*ldc+j), *(A+i*lda+l), *(B+l*ldb+j));
}
else
for (size_t i = 0; i < m; ++i)
for (size_t j = 0; j < n; ++j)
Expand Down
Loading