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

Do not use exceptions control flow #12

Open
wants to merge 5 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
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ namespace libfqfft {
FieldT arithmetic_generator;
void do_precomputation();

static bool valid_for_size(const size_t m);

arithmetic_sequence_domain(const size_t m);

void FFT(std::vector<FieldT> &a);
Expand Down
12 changes: 12 additions & 0 deletions libfqfft/evaluation_domain/domains/arithmetic_sequence_domain.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@

namespace libfqfft {

template<typename FieldT>
bool arithmetic_sequence_domain<FieldT>::valid_for_size(const size_t m)
{
if (m <=1)
return false;

if (FieldT::arithmetic_generator() == FieldT::zero())
return false;

return true;
}

template<typename FieldT>
arithmetic_sequence_domain<FieldT>::arithmetic_sequence_domain(const size_t m) : evaluation_domain<FieldT>(m)
{
Expand Down
2 changes: 2 additions & 0 deletions libfqfft/evaluation_domain/domains/basic_radix2_domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class basic_radix2_domain : public evaluation_domain<FieldT> {

FieldT omega;

static bool valid_for_size(const size_t m);

basic_radix2_domain(const size_t m);

void FFT(std::vector<FieldT> &a);
Expand Down
21 changes: 21 additions & 0 deletions libfqfft/evaluation_domain/domains/basic_radix2_domain.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,27 @@

namespace libfqfft {

template<typename FieldT>
bool basic_radix2_domain<FieldT>::valid_for_size(const size_t m)
{
if ( m <= 1 )
return false;

// Will `get_root_of_unity` throw?
if (!std::is_same<FieldT, libff::Double>::value)
{
const size_t logm = libff::log2(m);

if (logm > FieldT::s)
return false;
}

if( get_root_of_unity_will_throw<FieldT>(m) )
return false;

return true;
}

template<typename FieldT>
basic_radix2_domain<FieldT>::basic_radix2_domain(const size_t m) : evaluation_domain<FieldT>(m)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void _basic_serial_radix2_FFT(std::vector<FieldT> &a, const FieldT &omega)
// w_m is 2^s-th root of unity now
const FieldT w_m = omega^(n/(2*m));

asm volatile ("/* pre-inner */");
//asm volatile ("/* pre-inner */");
for (size_t k = 0; k < n; k += 2*m)
{
FieldT w = FieldT::one();
Expand All @@ -73,7 +73,7 @@ void _basic_serial_radix2_FFT(std::vector<FieldT> &a, const FieldT &omega)
w *= w_m;
}
}
asm volatile ("/* post-inner */");
//asm volatile ("/* post-inner */");
m *= 2;
}
}
Expand Down
2 changes: 2 additions & 0 deletions libfqfft/evaluation_domain/domains/extended_radix2_domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class extended_radix2_domain : public evaluation_domain<FieldT> {
FieldT omega;
FieldT shift;

static bool valid_for_size(const size_t m);

extended_radix2_domain(const size_t m);

void FFT(std::vector<FieldT> &a);
Expand Down
23 changes: 23 additions & 0 deletions libfqfft/evaluation_domain/domains/extended_radix2_domain.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@

namespace libfqfft {

template<typename FieldT>
bool extended_radix2_domain<FieldT>::valid_for_size(const size_t m)
{
if ( m <= 1 )
return false;

// Will `get_root_of_unity` throw?
if (!std::is_same<FieldT, libff::Double>::value)
{
const size_t logm = libff::log2(m);

if (logm != (FieldT::s + 1))
return false;
}

size_t small_m = m / 2;

if( get_root_of_unity_will_throw<FieldT>(small_m) )
return false;

return true;
}

template<typename FieldT>
extended_radix2_domain<FieldT>::extended_radix2_domain(const size_t m) : evaluation_domain<FieldT>(m)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ namespace libfqfft {
std::vector<FieldT> geometric_triangular_sequence;
void do_precomputation();

static bool valid_for_size(const size_t m);

geometric_sequence_domain(const size_t m);

void FFT(std::vector<FieldT> &a);
Expand Down
12 changes: 12 additions & 0 deletions libfqfft/evaluation_domain/domains/geometric_sequence_domain.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@

namespace libfqfft {

template<typename FieldT>
bool geometric_sequence_domain<FieldT>::valid_for_size(const size_t m)
{
if ( m <= 1 )
return false;

if (FieldT::geometric_generator() == FieldT::zero())
return false;

return true;
}

template<typename FieldT>
geometric_sequence_domain<FieldT>::geometric_sequence_domain(const size_t m) : evaluation_domain<FieldT>(m)
{
Expand Down
2 changes: 2 additions & 0 deletions libfqfft/evaluation_domain/domains/step_radix2_domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ class step_radix2_domain : public evaluation_domain<FieldT> {
FieldT big_omega;
FieldT small_omega;

static bool valid_for_size(const size_t m);

step_radix2_domain(const size_t m);

void FFT(std::vector<FieldT> &a);
Expand Down
23 changes: 23 additions & 0 deletions libfqfft/evaluation_domain/domains/step_radix2_domain.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@

namespace libfqfft {

template<typename FieldT>
bool step_radix2_domain<FieldT>::valid_for_size(const size_t m)
{
if ( m <= 1 )
return false;

const size_t big_m = 1ul<<(libff::log2(m)-1);
const size_t small_m = m - big_m;

if (small_m != 1ul<<libff::log2(small_m))
return false;

// omega
if( get_root_of_unity_will_throw<FieldT>(1ul<<libff::log2(m)) )
return false;

// small_omega
if( get_root_of_unity_will_throw<FieldT>(1ul<<libff::log2(small_m)) )
return false;

return true;
}

template<typename FieldT>
step_radix2_domain<FieldT>::step_radix2_domain(const size_t m) : evaluation_domain<FieldT>(m)
{
Expand Down
25 changes: 25 additions & 0 deletions libfqfft/evaluation_domain/evaluation_domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,34 @@
#define EVALUATION_DOMAIN_HPP_

#include <vector>
#include <libff/common/double.hpp>

namespace libfqfft {

template<typename FieldT>
typename std::enable_if<std::is_same<FieldT, libff::Double>::value, bool>::type
get_root_of_unity_will_throw(const size_t n)
{
return false;
}


template<typename FieldT>
typename std::enable_if<!std::is_same<FieldT, libff::Double>::value, bool>::type
get_root_of_unity_will_throw(const size_t n)
{
const size_t logn = libff::log2(n);

if (n != (1u << logn))
return true;

if (logn > FieldT::s)
return true;

return false;
}


/**
* An evaluation domain.
*/
Expand Down
36 changes: 27 additions & 9 deletions libfqfft/evaluation_domain/get_evaluation_domain.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,33 @@ std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t m
const size_t small = min_size - big;
const size_t rounded_small = (1ul<<libff::log2(small));

try { result.reset(new basic_radix2_domain<FieldT>(min_size)); }
catch(...) { try { result.reset(new extended_radix2_domain<FieldT>(min_size)); }
catch(...) { try { result.reset(new step_radix2_domain<FieldT>(min_size)); }
catch(...) { try { result.reset(new basic_radix2_domain<FieldT>(big + rounded_small)); }
catch(...) { try { result.reset(new extended_radix2_domain<FieldT>(big + rounded_small)); }
catch(...) { try { result.reset(new step_radix2_domain<FieldT>(big + rounded_small)); }
catch(...) { try { result.reset(new geometric_sequence_domain<FieldT>(min_size)); }
catch(...) { try { result.reset(new arithmetic_sequence_domain<FieldT>(min_size)); }
catch(...) { throw DomainSizeException("get_evaluation_domain: no matching domain"); }}}}}}}}
if ( basic_radix2_domain<FieldT>::valid_for_size(min_size) ) {
result.reset(new basic_radix2_domain<FieldT>(min_size));
}
else if ( extended_radix2_domain<FieldT>::valid_for_size(min_size) ) {
result.reset(new extended_radix2_domain<FieldT>(min_size));
}
else if ( step_radix2_domain<FieldT>::valid_for_size(min_size) ) {
result.reset(new step_radix2_domain<FieldT>(min_size));
}
else if ( basic_radix2_domain<FieldT>::valid_for_size(big + rounded_small) ) {
result.reset(new basic_radix2_domain<FieldT>(big + rounded_small));
}
else if ( extended_radix2_domain<FieldT>::valid_for_size(big + rounded_small) ) {
result.reset(new extended_radix2_domain<FieldT>(big + rounded_small));
}
else if ( step_radix2_domain<FieldT>::valid_for_size(big + rounded_small) ) {
result.reset(new step_radix2_domain<FieldT>(big + rounded_small));
}
else if ( geometric_sequence_domain<FieldT>::valid_for_size(min_size) ) {
result.reset(new geometric_sequence_domain<FieldT>(min_size));
}
else if ( arithmetic_sequence_domain<FieldT>::valid_for_size(min_size) ) {
result.reset(new arithmetic_sequence_domain<FieldT>(min_size));
}
else {
throw DomainSizeException("get_evaluation_domain: no matching domain");
}

return result;
}
Expand Down