Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solve paladin cra #227

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
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
8 changes: 5 additions & 3 deletions benchmarks/benchmark-dense-solve.C
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ int main(int argc, char** argv)
{'n', "-n", "Set the matrix dimension.", TYPE_INT, &args.n},
{'b', "-b", "bit size", TYPE_INT, &args.bits},
{'s', "-s", "Seed for randomness.", TYPE_INT, &args.seed},
{'d', "-d", "Dispatch mode (any of: Auto, Sequential, SMP, Distributed).", TYPE_STR, &args.dispatchString},
{'d', "-d", "Dispatch mode (any of: Auto, Sequential, Distributed).", TYPE_STR, &args.dispatchString},
{'t', "-t", "Number of threads.", TYPE_INT, &numThreads },
{'M', "-M",
"Choose the solve method (any of: Auto, Elimination, DenseElimination, SparseElimination, "
Expand All @@ -154,6 +154,7 @@ int main(int argc, char** argv)
END_OF_ARGUMENTS};
LinBox::parseArguments(argc, argv, as);


if (numThreads > 0) {
omp_set_num_threads(numThreads);
}
Expand All @@ -172,7 +173,7 @@ int main(int argc, char** argv)
MethodBase method;
method.pCommunicator = &communicator;
if (args.dispatchString == "Sequential") method.dispatch = Dispatch::Sequential;
else if (args.dispatchString == "SMP") method.dispatch = Dispatch::SMP;
else if (args.dispatchString == "Paladin") method.dispatch = Dispatch::Paladin;
else if (args.dispatchString == "Distributed") method.dispatch = Dispatch::Distributed;
else method.dispatch = Dispatch::Auto;

Expand Down Expand Up @@ -208,4 +209,5 @@ int main(int argc, char** argv)
}

return 0;
}

}
2 changes: 1 addition & 1 deletion examples/minpoly.C
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ int main (int argc, char **argv)
#ifdef __LINBOX_HAVE_MPI
Communicator C(&argc, &argv);
process = C.rank();
M.communicatorp(&C);
//M.communicatorp(&C);
#endif

Givaro::ZRing<Integer> ZZ;
Expand Down
7 changes: 4 additions & 3 deletions linbox/algorithms/cra-domain-omp.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <omp.h>
#include <set>
#include "linbox/algorithms/cra-domain-sequential.h"
#include "linbox/algorithms/rational-cra.h"

namespace LinBox
{
Expand Down Expand Up @@ -90,10 +91,10 @@ namespace LinBox

#pragma omp parallel for
for(size_t i=0;i<NN;++i) {
ROUNDresults[i] = Iteration(ROUNDresidues[i], ROUNDdomains[i]);
Iteration(ROUNDresidues[i], ROUNDdomains[i]);//ROUNDresults[i] = Iteration(ROUNDresidues[i], ROUNDdomains[i]);
}
#pragma omp barrier

/*
// if any thread says RESTART, then all CONTINUEs become SKIPs
bool anyrestart = false;
for (auto res : ROUNDresults) {
Expand Down Expand Up @@ -122,7 +123,7 @@ namespace LinBox
}
}
//std::cerr << "Computed: " << iterCount() << " primes." << std::endl;
}
*/ }

// commentator().stop ("done", NULL, "mmcrait");
//std::cerr << "Used: " << this->iterCount() << " primes." << std::endl;
Expand Down
205 changes: 205 additions & 0 deletions linbox/algorithms/cra-paladin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/* linbox/algorithms/cra-domain-omp.h
* Copyright (C) 1999-2010 The LinBox group
*
* Updated by Hongguang Zhu <[email protected]>
*
*
* Naive parallel chinese remaindering
* Launch NN iterations in parallel, where NN=omp_get_num_threads()
* Then synchronization and termintation test.
* Time-stamp: <13 Mar 12 13:49:58 [email protected]>
*
* ========LICENCE========
* This file is part of the library LinBox.
*
* LinBox is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* ========LICENCE========
*/

/*! @file algorithms/cra-domain-omp.h
* @brief Parallel (OMP) version of \ref CRA
* @ingroup CRA
*/

#ifndef __LINBOX_omp_cra_H
#define __LINBOX_omp_cra_H
// commentator is not thread safe
//#define DISABLE_COMMENTATOR
#include <omp.h>

#include <set>
#include "linbox/randiter/random-prime.h"
#include "linbox/algorithms/rational-cra.h"

namespace LinBox
{

template<class CRABase>
struct RationalChineseRemainderPaladin {
typedef typename CRABase::Domain Domain;
typedef typename CRABase::DomainElement DomainElement;
typedef RationalChineseRemainder<CRABase> Father_t;

CRABase Builder_;
double HB;//hadamard bound
int Niter;

template<class Param>
RationalChineseRemainderPaladin(const Param& b) :
Builder_(b), HB(b), Niter(0)
{}

template<class Function, class PrimeIterator>
Integer& operator() (Integer& res, Function& Iteration, PrimeIterator& primeiter)
{

this->para_compute<Integer>(Iteration,primeiter);
// commentator().stop ("done", NULL, "mmcrait");

return this->Builder_.result(res);
}

// @fixme REMOVE ?
template<class Container, class Function, class PrimeIterator>
Container& operator() (Container& res, Function& Iteration, PrimeIterator& primeiter)
{

this->para_compute<Container>(Iteration,primeiter);

// commentator().stop ("done", NULL, "mmcrait");

return this->Builder_.result(res);
}


template<class Function, class PrimeIterator>
Integer& operator() (Integer& res, Integer& den, Function& Iteration, PrimeIterator& primeiter)
{

this->para_compute<Integer>(Iteration,primeiter);

// commentator().stop ("done", NULL, "mmcrait");

return this->Builder_.result(res,den);
}


template<class Vect, class Function, class PrimeIterator>
Vect& operator() (Vect& num, Vect& den, Function& Iteration, PrimeIterator& primeiter)
{

this->para_compute<BlasVector<Domain>>(Iteration,primeiter); // @fixme Should be rebind of Vect into Domain

// commentator().stop ("done", NULL, "mmcrait");

return this->Builder_.result(num,den);
}


template<class ResidueType, class Function, class PrimeIterator>
void para_compute(Function &Iteration, PrimeIterator& primeiter){
this->Niter = std::ceil(1.442695040889*HB/(double)(primeiter.getBits()-1));
std::vector<ResidueType> ROUNDresidues;
ROUNDresidues.resize(this->Niter);
LinBox::PrimeIterator<LinBox::IteratorCategories::DeterministicTag> gen(primeiter.getBits());
std::vector<int> m_primeiters;m_primeiters.reserve(this->Niter);

for(auto j=0;j<Niter;j++){
++gen;
while(this->Builder_.noncoprime(*gen) )
++primeiter;
m_primeiters.push_back(*gen);
}

this->compute_task(m_primeiters, Iteration, ROUNDresidues);


}


template< class Function, class ResidueType>
void solve_with_prime(int m_primeiter, Function& Iteration, ResidueType& ROUNDresidue)
{

Domain D(m_primeiter);
Iteration(ROUNDresidue, D);
}


template<class Function, class PrimeIterator, class ResidueType>
void compute_task(std::vector<PrimeIterator>& m_primeiters,
Function& Iteration, std::vector<ResidueType>& ROUNDresidues)
{

long NN = this->Niter;
#if 0
PAR_BLOCK{
auto sp=SPLITTER(NUM_THREADS,FFLAS::CuttingStrategy::Row,FFLAS::StrategyParameter::Threads);
SYNCH_GROUP({
FORBLOCK1D(iter, NN, sp,{
TASK(MODE(CONSTREFERENCE(m_primeiters,Iteration,ROUNDresidues)),{
for(auto j=iter.begin(); j!=iter.end(); ++j)
{

solve_with_prime(m_primeiters[j], Iteration, ROUNDresidues[j]);
}
})
})

})
}
#else
PAR_BLOCK{
auto sp=SPLITTER(NUM_THREADS,FFLAS::CuttingStrategy::Row,FFLAS::StrategyParameter::Threads);
FOR1D(iter, NN, sp, MODE(CONSTREFERENCE(m_primeiters,Iteration,ROUNDresidues)),
{
solve_with_prime(m_primeiters[iter], Iteration, ROUNDresidues[iter]);
})

}
#endif
Domain D(m_primeiters[0]);
this->Builder_.initialize( D, ROUNDresidues[0]);
for(auto j=1;j<NN;j++){
Domain D(m_primeiters[j]);
this->Builder_.progress( D, ROUNDresidues[j]);
}
}


template<class Container, class Function, class PrimeIterator>
Container& operator() (Container& res, Integer& den, Function& Iteration, PrimeIterator& primeiter)
{

this->para_compute<BlasVector<Domain>>(Iteration,primeiter); // @fixme SHould be container -> rebind

// commentator().stop ("done", NULL, "mmcrait");

return this->Builder_.result(res,den);

}

};

}
#endif //__LINBOX_omp_cra_H

// Local Variables:
// mode: C++
// tab-width: 4
// indent-tabs-mode: nil
// c-basic-offset: 4
// End:
// vim:sts=4:sw=4:ts=4:et:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
2 changes: 1 addition & 1 deletion linbox/solutions/methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ namespace LinBox {
enum class Dispatch {
Auto, //!< Let implementation decide what to use.
Sequential, //!< All sub-computations are done sequentially.
SMP, //!< Use symmetric multiprocessing (Paladin) to do sub-computations.
Distributed, //!< Use MPI to distribute sub-computations accross nodes.
Combined, //!< Use MPI then Paladin on each node.
Paladin, //!< Use Paladin for multithreading.
};

/**
Expand Down
6 changes: 5 additions & 1 deletion linbox/solutions/solve/solve-cra.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*/

#pragma once

#include <linbox/algorithms/cra-paladin.h>
#include <linbox/algorithms/cra-distributed.h>
#include <linbox/algorithms/rational-cra-builder-early-multip.h>
#include <linbox/algorithms/rational-cra-builder-full-multip.h>
Expand Down Expand Up @@ -180,6 +180,10 @@ namespace LinBox {
cra(num, den, iteration, primeGenerator);
}
#endif
else if (dispatch == Dispatch::Paladin) {
LinBox::RationalChineseRemainderPaladin<CRAAlgorithm> cra(hadamardLogBound);
cra(num, den, iteration, primeGenerator);
}
else {
throw LinBox::NotImplementedYet("Integer CRA Solve with specified dispatch type is not implemented yet.");
}
Expand Down
6 changes: 6 additions & 0 deletions linbox/util/mpicpp.inl
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ namespace LinBox {
unserialize(value, bytes);
}
}
//Specialization for Bcast with only one boolean value data
template <> void Communicator::bcast(bool& value, int src)
{
MPI_Bcast(&value, 1, MPI::BOOL, src, _comm);

}
}

// Local Variables:
Expand Down
11 changes: 6 additions & 5 deletions tests/test-solve-full.C
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ int main(int argc, char** argv)
{'B', "-B", "Vector bit size for rational solve tests (defaults to -b if not specified).", TYPE_INT, &vectorBitSize},
{'m', "-m", "Row dimension of matrices.", TYPE_INT, &m},
{'n', "-n", "Column dimension of matrices.", TYPE_INT, &n},
{'d', "-d", "Dispatch mode (either Auto, Sequential, SMP or Distributed).", TYPE_STR, &dispatchString},
{'d', "-d", "Dispatch mode (either Auto, Sequential, Paladin or Distributed).", TYPE_STR, &dispatchString},
END_OF_ARGUMENTS};

parseArguments(argc, argv, args);
Expand All @@ -237,10 +237,10 @@ int main(int argc, char** argv)
method.dispatch = Dispatch::Distributed;
else if (dispatchString == "Sequential")
method.dispatch = Dispatch::Sequential;
else if (dispatchString == "SMP")
method.dispatch = Dispatch::SMP;
else if (dispatchString == "Paladin")
method.dispatch = Dispatch::Paladin;
else if (dispatchString != "Auto") {
std::cerr << "-d Dispatch mode should be either Auto, Sequential, SMP or Distributed" << std::endl;
std::cerr << "-d Dispatch mode should be either Auto, Sequential, SMP, Paladin or Distributed" << std::endl;
return EXIT_FAILURE;
}

Expand All @@ -262,6 +262,7 @@ int main(int argc, char** argv)

bool ok = true;
do {

// ----- Rational Auto
ok = ok && test_dense_solve(Method::Auto(method), ZZ, QQ, m, n, bitSize, vectorBitSize, seed, verbose);
ok = ok && test_sparse_solve(Method::Auto(method), ZZ, QQ, m, n, bitSize, vectorBitSize, seed, verbose);
Expand All @@ -275,7 +276,7 @@ int main(int argc, char** argv)
// ----- Rational CRA
// @fixme @bug When bitSize = 5 and vectorBitSize = 50, CRA fails
ok = ok && test_dense_solve(Method::CRAAuto(method), ZZ, QQ, m, n, bitSize, vectorBitSize, seed, verbose);
ok = ok && test_sparse_solve(Method::CRAAuto(method), ZZ, QQ, m, n, bitSize, vectorBitSize, seed, verbose);
// ok = ok && test_sparse_solve(Method::CRAAuto(method), ZZ, QQ, m, n, bitSize, vectorBitSize, seed, verbose);
// ok = ok && test_blackbox_solve(Method::CRAAuto(method), ZZ, QQ, m, n, bitSize, vectorBitSize, seed, verbose);

ok = ok && test_dense_solve(Method::CRAAuto(method), QQ, QQ, m, n, bitSize, vectorBitSize, seed, verbose);
Expand Down