<commit_before>#define BOOST_TEST_MODULE "test_vector"

#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
#include <boost/test/unit_test.hpp>
#else
#define BOOST_TEST_NO_LIB
#include <boost/test/included/unit_test.hpp>
#endif

#include <mjolnir/math/Vector.hpp>

#include <random>
using namespace mjolnir;
typedef double real_type;
typedef mjolnir::Vector<double, 3> Vector3d;
constexpr static unsigned int seed = 32479327;
constexpr static std::size_t N = 10000;
constexpr static real_type tolerance = 1e-8;

BOOST_AUTO_TEST_CASE(test_vector_add)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const Vector3d sum = lhs + rhs;
        BOOST_CHECK_CLOSE_FRACTION(sum[0], lhs[0] + rhs[0], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sum[1], lhs[1] + rhs[1], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sum[2], lhs[2] + rhs[2], tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_subtract)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const Vector3d sub = lhs - rhs;
        BOOST_CHECK_CLOSE_FRACTION(sub[0], lhs[0] - rhs[0], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sub[1], lhs[1] - rhs[1], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sub[2], lhs[2] - rhs[2], tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_scalar_multiple)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const real_type rhs = uni(mt);
        const Vector3d mul = lhs * rhs;
        BOOST_CHECK_CLOSE_FRACTION(mul[0], lhs[0] * rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(mul[1], lhs[1] * rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(mul[2], lhs[2] * rhs, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_scalar_division)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const real_type rhs = uni(mt);
        const Vector3d div = lhs / rhs;
        BOOST_CHECK_CLOSE_FRACTION(div[0], lhs[0] / rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(div[1], lhs[1] / rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(div[2], lhs[2] / rhs, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_dot_product)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const real_type dot = dot_product(lhs, rhs);
        BOOST_CHECK_CLOSE_FRACTION(dot, lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2], tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_length)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const real_type dot = dot_product(lhs, lhs);
        const real_type lensq = length_sq(lhs);
        BOOST_CHECK_CLOSE_FRACTION(lensq, dot, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_cross_product)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const Vector3d cross = cross_product(lhs, rhs);
        const real_type dotl = dot_product(cross, lhs);
        const real_type dotr = dot_product(cross, rhs);
        BOOST_CHECK_SMALL(dotl, tolerance);
        BOOST_CHECK_SMALL(dotr, tolerance);
        const real_type lenc = length(cross);

        const real_type lenl = length(lhs);
        const real_type lenr = length(rhs);
        const real_type dot  = dot_product(lhs, rhs);
        const real_type cost = dot / (lenl * lenr);
        const real_type sint = std::sqrt(1. - cost * cost);

        BOOST_CHECK_CLOSE_FRACTION(lenc, lenl * lenr * sint, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_scalar_triple_product)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d mid(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const real_type tri = scalar_triple_product(lhs, mid, rhs);
        BOOST_CHECK_CLOSE_FRACTION(tri, dot_product(cross_product(lhs, mid), rhs), tolerance);
        BOOST_CHECK_CLOSE_FRACTION(tri, dot_product(lhs, cross_product(mid, rhs)), tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_rotation)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    const Vector3d unit_x(1., 0., 0.);
    const Vector3d unit_z(0., 0., 1.);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const real_type theta = uni(mt) * M_PI;
        const Vector3d rot = rotate(theta, unit_z, unit_x);
        BOOST_CHECK_CLOSE_FRACTION(length(rot), 1., tolerance);
        BOOST_CHECK_CLOSE_FRACTION(rot[0], std::cos(theta), tolerance);
        BOOST_CHECK_CLOSE_FRACTION(rot[1], std::sin(theta), tolerance);
        BOOST_CHECK_SMALL(rot[2], tolerance);
    }
}

<commit_msg>remove M_PI macro<commit_after>#define BOOST_TEST_MODULE "test_vector"

#ifdef UNITTEST_FRAMEWORK_LIBRARY_EXIST
#include <boost/test/unit_test.hpp>
#else
#define BOOST_TEST_NO_LIB
#include <boost/test/included/unit_test.hpp>
#endif

#include <mjolnir/math/Vector.hpp>

#include <random>
using namespace mjolnir;
typedef double real_type;
typedef mjolnir::Vector<double, 3> Vector3d;
constexpr static unsigned int seed = 32479327;
constexpr static std::size_t N = 10000;
constexpr static real_type tolerance = 1e-8;

BOOST_AUTO_TEST_CASE(test_vector_add)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const Vector3d sum = lhs + rhs;
        BOOST_CHECK_CLOSE_FRACTION(sum[0], lhs[0] + rhs[0], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sum[1], lhs[1] + rhs[1], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sum[2], lhs[2] + rhs[2], tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_subtract)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const Vector3d sub = lhs - rhs;
        BOOST_CHECK_CLOSE_FRACTION(sub[0], lhs[0] - rhs[0], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sub[1], lhs[1] - rhs[1], tolerance);
        BOOST_CHECK_CLOSE_FRACTION(sub[2], lhs[2] - rhs[2], tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_scalar_multiple)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const real_type rhs = uni(mt);
        const Vector3d mul = lhs * rhs;
        BOOST_CHECK_CLOSE_FRACTION(mul[0], lhs[0] * rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(mul[1], lhs[1] * rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(mul[2], lhs[2] * rhs, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_scalar_division)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const real_type rhs = uni(mt);
        const Vector3d div = lhs / rhs;
        BOOST_CHECK_CLOSE_FRACTION(div[0], lhs[0] / rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(div[1], lhs[1] / rhs, tolerance);
        BOOST_CHECK_CLOSE_FRACTION(div[2], lhs[2] / rhs, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_dot_product)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const real_type dot = dot_product(lhs, rhs);
        BOOST_CHECK_CLOSE_FRACTION(dot, lhs[0] * rhs[0] + lhs[1] * rhs[1] + lhs[2] * rhs[2], tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_length)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const real_type dot = dot_product(lhs, lhs);
        const real_type lensq = length_sq(lhs);
        BOOST_CHECK_CLOSE_FRACTION(lensq, dot, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_cross_product)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const Vector3d cross = cross_product(lhs, rhs);
        const real_type dotl = dot_product(cross, lhs);
        const real_type dotr = dot_product(cross, rhs);
        BOOST_CHECK_SMALL(dotl, tolerance);
        BOOST_CHECK_SMALL(dotr, tolerance);
        const real_type lenc = length(cross);

        const real_type lenl = length(lhs);
        const real_type lenr = length(rhs);
        const real_type dot  = dot_product(lhs, rhs);
        const real_type cost = dot / (lenl * lenr);
        const real_type sint = std::sqrt(1. - cost * cost);

        BOOST_CHECK_CLOSE_FRACTION(lenc, lenl * lenr * sint, tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_scalar_triple_product)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const Vector3d lhs(uni(mt), uni(mt), uni(mt));
        const Vector3d mid(uni(mt), uni(mt), uni(mt));
        const Vector3d rhs(uni(mt), uni(mt), uni(mt));
        const real_type tri = scalar_triple_product(lhs, mid, rhs);
        BOOST_CHECK_CLOSE_FRACTION(tri, dot_product(cross_product(lhs, mid), rhs), tolerance);
        BOOST_CHECK_CLOSE_FRACTION(tri, dot_product(lhs, cross_product(mid, rhs)), tolerance);
    }
}

BOOST_AUTO_TEST_CASE(test_vector_rotation)
{
    std::mt19937 mt(seed);
    std::uniform_real_distribution<real_type> uni(-1.0, 1.0);
    const Vector3d unit_x(1., 0., 0.);
    const Vector3d unit_z(0., 0., 1.);
    for(std::size_t test_times=0; test_times<N; ++test_times)
    {
        const real_type theta = uni(mt) * 3.14159265358979;
        const Vector3d rot = rotate(theta, unit_z, unit_x);
        BOOST_CHECK_CLOSE_FRACTION(length(rot), 1., tolerance);
        BOOST_CHECK_CLOSE_FRACTION(rot[0], std::cos(theta), tolerance);
        BOOST_CHECK_CLOSE_FRACTION(rot[1], std::sin(theta), tolerance);
        BOOST_CHECK_SMALL(rot[2], tolerance);
    }
}

<|endoftext|>


<commit_before>//===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This program is an automated compiler debugger tool.  It is used to narrow
// down miscompilations and crash problems to a specific pass in the compiler,
// and the specific Module or Function input that is causing the problem.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ToolRunner.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Valgrind.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

//Enable this macro to debug bugpoint itself.
//#define DEBUG_BUGPOINT 1

using namespace llvm;

static cl::opt<bool>
FindBugs("find-bugs", cl::desc("Run many different optimization sequences "
                               "on program to find bugs"), cl::init(false));

static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
               cl::desc("<input llvm ll/bc files>"));

static cl::opt<unsigned>
TimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"),
             cl::desc("Number of seconds program is allowed to run before it "
                      "is killed (default is 300s), 0 disables timeout"));

static cl::opt<int>
MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"),
            cl::desc("Maximum amount of memory to use. 0 disables check."
                     " Defaults to 400MB (800MB under valgrind)."));

static cl::opt<bool>
UseValgrind("enable-valgrind",
            cl::desc("Run optimizations through valgrind"));

// The AnalysesList is automatically populated with registered Passes by the
// PassNameParser.
//
static cl::list<const PassInfo*, bool, PassNameParser>
PassList(cl::desc("Passes available:"), cl::ZeroOrMore);

static cl::opt<bool>
StandardLinkOpts("std-link-opts",
                 cl::desc("Include the standard link time optimizations"));

static cl::opt<bool>
OptLevelO1("O1",
           cl::desc("Optimization level 1. Identical to 'opt -O1'"));

static cl::opt<bool>
OptLevelO2("O2",
           cl::desc("Optimization level 2. Identical to 'opt -O2'"));

static cl::opt<bool>
OptLevelO3("O3",
           cl::desc("Optimization level 3. Identical to 'opt -O3'"));

static cl::opt<std::string>
OverrideTriple("mtriple", cl::desc("Override target triple for module"));

/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
bool llvm::BugpointIsInterrupted = false;

#ifndef DEBUG_BUGPOINT
static void BugpointInterruptFunction() {
  BugpointIsInterrupted = true;
}
#endif

// Hack to capture a pass list.
namespace {
  class AddToDriver : public legacy::FunctionPassManager {
    BugDriver &D;
  public:
    AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {}

    void add(Pass *P) override {
      const void *ID = P->getPassID();
      const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
      D.addPass(PI->getPassArgument());
    }
  };
}

#ifdef LINK_POLLY_INTO_TOOLS
namespace polly {
void initializePollyPasses(llvm::PassRegistry &Registry);
}
#endif

int main(int argc, char **argv) {
#ifndef DEBUG_BUGPOINT
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
#endif

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

#ifdef LINK_POLLY_INTO_TOOLS
  polly::initializePollyPasses(Registry);
#endif

  cl::ParseCommandLineOptions(argc, argv,
                              "LLVM automatic testcase reducer. See\nhttp://"
                              "llvm.org/cmds/bugpoint.html"
                              " for more information.\n");
#ifndef DEBUG_BUGPOINT
  sys::SetInterruptFunction(BugpointInterruptFunction);
#endif

  LLVMContext Context;
  // If we have an override, set it and then track the triple we want Modules
  // to use.
  if (!OverrideTriple.empty()) {
    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
  }

  if (MemoryLimit < 0) {
    // Set the default MemoryLimit.  Be sure to update the flag's description if
    // you change this.
    if (sys::RunningOnValgrind() || UseValgrind)
      MemoryLimit = 800;
    else
      MemoryLimit = 400;
  }

  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit,
              UseValgrind, Context);
  if (D.addSources(InputFilenames)) return 1;

  AddToDriver PM(D);

  if (StandardLinkOpts) {
    PassManagerBuilder Builder;
    Builder.Inliner = createFunctionInliningPass();
    Builder.populateLTOPassManager(PM);
  }

  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    PassManagerBuilder Builder;
    if (OptLevelO1)
      Builder.Inliner = createAlwaysInlinerPass();
    else if (OptLevelO2)
      Builder.Inliner = createFunctionInliningPass(225);
    else
      Builder.Inliner = createFunctionInliningPass(275);
    Builder.populateFunctionPassManager(PM);
    Builder.populateModulePassManager(PM);
  }

  for (const PassInfo *PI : PassList)
    D.addPass(PI->getPassArgument());

  // Bugpoint has the ability of generating a plethora of core files, so to
  // avoid filling up the disk, we prevent it
#ifndef DEBUG_BUGPOINT
  sys::Process::PreventCoreFiles();
#endif

  std::string Error;
  bool Failure = D.run(Error);
  if (!Error.empty()) {
    errs() << Error;
    return 1;
  }
  return Failure;
}
<commit_msg>[bugpoint] Add a -Os option<commit_after>//===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This program is an automated compiler debugger tool.  It is used to narrow
// down miscompilations and crash problems to a specific pass in the compiler,
// and the specific Module or Function input that is causing the problem.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ToolRunner.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/LinkAllIR.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Valgrind.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"

//Enable this macro to debug bugpoint itself.
//#define DEBUG_BUGPOINT 1

using namespace llvm;

static cl::opt<bool>
FindBugs("find-bugs", cl::desc("Run many different optimization sequences "
                               "on program to find bugs"), cl::init(false));

static cl::list<std::string>
InputFilenames(cl::Positional, cl::OneOrMore,
               cl::desc("<input llvm ll/bc files>"));

static cl::opt<unsigned>
TimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"),
             cl::desc("Number of seconds program is allowed to run before it "
                      "is killed (default is 300s), 0 disables timeout"));

static cl::opt<int>
MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"),
            cl::desc("Maximum amount of memory to use. 0 disables check."
                     " Defaults to 400MB (800MB under valgrind)."));

static cl::opt<bool>
UseValgrind("enable-valgrind",
            cl::desc("Run optimizations through valgrind"));

// The AnalysesList is automatically populated with registered Passes by the
// PassNameParser.
//
static cl::list<const PassInfo*, bool, PassNameParser>
PassList(cl::desc("Passes available:"), cl::ZeroOrMore);

static cl::opt<bool>
StandardLinkOpts("std-link-opts",
                 cl::desc("Include the standard link time optimizations"));

static cl::opt<bool>
OptLevelO1("O1",
           cl::desc("Optimization level 1. Identical to 'opt -O1'"));

static cl::opt<bool>
OptLevelO2("O2",
           cl::desc("Optimization level 2. Identical to 'opt -O2'"));

static cl::opt<bool>
OptLevelOs("Os",
           cl::desc("Like -O2 with extra optimizations for size. Similar to clang -Os"));

static cl::opt<bool>
OptLevelO3("O3",
           cl::desc("Optimization level 3. Identical to 'opt -O3'"));

static cl::opt<std::string>
OverrideTriple("mtriple", cl::desc("Override target triple for module"));

/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
bool llvm::BugpointIsInterrupted = false;

#ifndef DEBUG_BUGPOINT
static void BugpointInterruptFunction() {
  BugpointIsInterrupted = true;
}
#endif

// Hack to capture a pass list.
namespace {
  class AddToDriver : public legacy::FunctionPassManager {
    BugDriver &D;
  public:
    AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {}

    void add(Pass *P) override {
      const void *ID = P->getPassID();
      const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
      D.addPass(PI->getPassArgument());
    }
  };
}

#ifdef LINK_POLLY_INTO_TOOLS
namespace polly {
void initializePollyPasses(llvm::PassRegistry &Registry);
}
#endif

int main(int argc, char **argv) {
#ifndef DEBUG_BUGPOINT
  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
  llvm::PrettyStackTraceProgram X(argc, argv);
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
#endif

  // Initialize passes
  PassRegistry &Registry = *PassRegistry::getPassRegistry();
  initializeCore(Registry);
  initializeScalarOpts(Registry);
  initializeObjCARCOpts(Registry);
  initializeVectorization(Registry);
  initializeIPO(Registry);
  initializeAnalysis(Registry);
  initializeTransformUtils(Registry);
  initializeInstCombine(Registry);
  initializeInstrumentation(Registry);
  initializeTarget(Registry);

#ifdef LINK_POLLY_INTO_TOOLS
  polly::initializePollyPasses(Registry);
#endif

  cl::ParseCommandLineOptions(argc, argv,
                              "LLVM automatic testcase reducer. See\nhttp://"
                              "llvm.org/cmds/bugpoint.html"
                              " for more information.\n");
#ifndef DEBUG_BUGPOINT
  sys::SetInterruptFunction(BugpointInterruptFunction);
#endif

  LLVMContext Context;
  // If we have an override, set it and then track the triple we want Modules
  // to use.
  if (!OverrideTriple.empty()) {
    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
  }

  if (MemoryLimit < 0) {
    // Set the default MemoryLimit.  Be sure to update the flag's description if
    // you change this.
    if (sys::RunningOnValgrind() || UseValgrind)
      MemoryLimit = 800;
    else
      MemoryLimit = 400;
  }

  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit,
              UseValgrind, Context);
  if (D.addSources(InputFilenames)) return 1;

  AddToDriver PM(D);

  if (StandardLinkOpts) {
    PassManagerBuilder Builder;
    Builder.Inliner = createFunctionInliningPass();
    Builder.populateLTOPassManager(PM);
  }

  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
    PassManagerBuilder Builder;
    if (OptLevelO1)
      Builder.Inliner = createAlwaysInlinerPass();
    else if (OptLevelOs || OptLevelO2)
      Builder.Inliner = createFunctionInliningPass(2, OptLevelOs ? 1 : 0);
    else
      Builder.Inliner = createFunctionInliningPass(275);
    Builder.populateFunctionPassManager(PM);
    Builder.populateModulePassManager(PM);
  }

  for (const PassInfo *PI : PassList)
    D.addPass(PI->getPassArgument());

  // Bugpoint has the ability of generating a plethora of core files, so to
  // avoid filling up the disk, we prevent it
#ifndef DEBUG_BUGPOINT
  sys::Process::PreventCoreFiles();
#endif

  std::string Error;
  bool Failure = D.run(Error);
  if (!Error.empty()) {
    errs() << Error;
    return 1;
  }
  return Failure;
}
<|endoftext|>


<commit_before>/* Copyright 2018 Ivan Tyulyandin and CyberTech Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "cameraDevice.h"

#include <QtCore/QSysInfo>

#include "qtCameraImplementation.h"
#include "v4l2CameraImplementation.h"
#include "imitationCameraImplementation.h"
#include <QsLog.h>
#include <trikKernel/configurer.h>

#include <QEventLoop>
#include <QThread>
#include <functional>

namespace trikControl {

CameraDevice::CameraDevice(const QString & mediaPath, const trikKernel::Configurer &configurer
							, trikHal::HardwareAbstractionInterface &hardwareAbstraction)
{
	Q_UNUSED(hardwareAbstraction);

	QString type = configurer.attributeByDevice("camera", "type");
	QString src = configurer.attributeByDevice("camera", "src");

	QString failMessage;

	if (type == "qtmultimedia") {
			decltype(mCameraImpl)(new QtCameraImplementation(src)).swap(mCameraImpl);
	} else if (type == "v4l2") {
#ifdef Q_OS_LINUX
			decltype(mCameraImpl)(new V4l2CameraImplementation(src, hardwareAbstraction)).swap(mCameraImpl);
#else
			failMessage = "can use v4l2 only on Linux";
#endif
	} else if (type == "file") {
				QStringList filters = configurer.attributeByDevice("camera", "filters").split(',');
				decltype(mCameraImpl)(new ImitationCameraImplementation(filters, mediaPath)).swap(mCameraImpl);
	} else {
		failMessage = "unknown camera device type:" + type;
	}

	if (mCameraImpl) {
		mCameraImpl->setTempDir(mediaPath);
	} else {
		if (failMessage.isEmpty()) {
			failMessage = "object construction failure";
		}

		QLOG_ERROR() << "Failed to initialize camera device for " << src
				<< ", " << failMessage
				<< ", creating camera with type=file ("
				<< mediaPath << ") and filters=\"*.jpg,*.png\"";
		decltype(mCameraImpl)(new ImitationCameraImplementation(QStringList({"*.jpg","*.png"}), mediaPath))
				.swap(mCameraImpl);
	}
}

QVector<uint8_t> CameraDevice::getPhoto() {
	if (!mCameraImpl) {
		return QVector<uint8_t>();
	}

	QMutexLocker lock(&mCameraMutex);
	QVector<uint8_t> photo;
	std::function<void()> runFunc = [this, &photo](){ mCameraImpl->getPhoto().swap(photo); };
#if QT_VERSION_MAJOR>=5 && QT_VERSION_MINOR>=10 && QT_VERSION_PATCH >= 2
	QScopedPointer<QThread> t(QThread::create(std::move(runFunc)));
#else
	struct CameraThread: public QThread {
		explicit CameraThread(std::function<void()> &&f): mF(f) {}
		void run() override { mF(); }
		std::function<void()> mF;
	};
	QScopedPointer<QThread> t(new CameraThread(std::move(runFunc)));
#endif
	QEventLoop l;
	QObject::connect(t.data(), &QThread::finished, &l, &QEventLoop::quit);
	t.data()->setObjectName(__PRETTY_FUNCTION__);
	t->start();
	l.exec();
	return photo;
}

CameraDevice::Status CameraDevice::status() const {
	return CameraDevice::Status::ready;
}
}
<commit_msg>Update trikControl/src/cameraDevice.cpp<commit_after>/* Copyright 2018 Ivan Tyulyandin and CyberTech Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "cameraDevice.h"

#include <QtCore/QSysInfo>

#include "qtCameraImplementation.h"
#include "v4l2CameraImplementation.h"
#include "imitationCameraImplementation.h"
#include <QsLog.h>
#include <trikKernel/configurer.h>

#include <QEventLoop>
#include <QThread>
#include <functional>

namespace trikControl {

CameraDevice::CameraDevice(const QString & mediaPath, const trikKernel::Configurer &configurer
							, trikHal::HardwareAbstractionInterface &hardwareAbstraction)
{
	Q_UNUSED(hardwareAbstraction);

	QString type = configurer.attributeByDevice("camera", "type");
	QString src = configurer.attributeByDevice("camera", "src");

	QString failMessage;

	if (type == "qtmultimedia") {
			decltype(mCameraImpl)(new QtCameraImplementation(src)).swap(mCameraImpl);
	} else if (type == "v4l2") {
#ifdef Q_OS_LINUX
			decltype(mCameraImpl)(new V4l2CameraImplementation(src, hardwareAbstraction)).swap(mCameraImpl);
#else
			failMessage = "can use v4l2 only on Linux";
#endif
	} else if (type == "file") {
				QStringList filters = configurer.attributeByDevice("camera", "filters").split(',');
				decltype(mCameraImpl)(new ImitationCameraImplementation(filters, mediaPath)).swap(mCameraImpl);
	} else {
		failMessage = "unknown camera device type:" + type;
	}

	if (mCameraImpl) {
		mCameraImpl->setTempDir(mediaPath);
	} else {
		if (failMessage.isEmpty()) {
			failMessage = "object construction failure";
		}

		QLOG_ERROR() << "Failed to initialize camera device for " << src
				<< ", " << failMessage
				<< ", creating camera with type=file ("
				<< mediaPath << ") and filters=\"*.jpg,*.png\"";
		decltype(mCameraImpl)(new ImitationCameraImplementation(QStringList({"*.jpg","*.png"}), mediaPath))
				.swap(mCameraImpl);
	}
}

QVector<uint8_t> CameraDevice::getPhoto() {
	if (!mCameraImpl) {
		return QVector<uint8_t>();
	}

	QMutexLocker lock(&mCameraMutex);
	QVector<uint8_t> photo;
	std::function<void()> runFunc = [this, &photo](){ mCameraImpl->getPhoto().swap(photo); };
#if QT_VERSION_MAJOR>=5 && QT_VERSION_MINOR>=10 && QT_VERSION_PATCH >= 2
	QScopedPointer<QThread> t(QThread::create(std::move(runFunc)));
#else
	struct CameraThread: public QThread {
		explicit CameraThread(std::function<void()> &&f): mF(f) {}
		void run() override { mF(); }
		std::function<void()> mF;
	};
	QScopedPointer<QThread> t(new CameraThread(std::move(runFunc)));
#endif
	QEventLoop l;
	QObject::connect(t.data(), &QThread::finished, &l, &QEventLoop::quit);
	t->setObjectName(__PRETTY_FUNCTION__);
	t->start();
	l.exec();
	return photo;
}

CameraDevice::Status CameraDevice::status() const {
	return CameraDevice::Status::ready;
}
}
<|endoftext|>


<commit_before>#include <Eigen/Core>
#include "drake/util/drakeGeometryUtil.h"
#include "drake/util/testUtil.h"
#include "drake/core/Gradient.h"
#include <iostream>
#include <cmath>

using namespace Eigen;
using namespace std;
using namespace Drake;

void testExpmap2quat(const Vector4d &quat);

void testRotationConversionFunctions()
{
  int ntests = 100;
  default_random_engine generator;
  // quat2axis, axis2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    auto a = quat2axis(q);
    auto q_back = axis2quat(a);
    valuecheck(acos(abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rotmat, rotmat2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Matrix3d R = quat2rotmat(q);
    Vector4d q_back = rotmat2quat(R);
    valuecheck(acos(abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rpy, rpy2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Vector3d rpy = quat2rpy(q);
    Vector4d q_back = rpy2quat(rpy);
    valuecheck(acos(abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // rotmat2axis, axis2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector4d a = rotmat2axis(R);
    Matrix3d R_back = axis2rotmat(a);
    valuecheckMatrix(R, R_back, 1e-6);
  }
  // rotmat2rpy, rpy2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector3d rpy = rotmat2rpy(R);
    Matrix3d R_back = rpy2rotmat(rpy);
    valuecheckMatrix(R, R_back, 1e-6);
  }
  // rpy2axis, axis2rpy
  for (int i = 0; i < ntests; i++) {
    Vector3d rpy = uniformlyRandomRPY(generator);
    Vector4d axis = rpy2axis(rpy);
    Vector3d rpy_back = axis2rpy(axis);
    valuecheckMatrix(rpy, rpy_back, 1e-6);
  }
  // expmap2quat, quat2expmap
  Vector4d quat_degenerate = Vector4d::Zero();
  quat_degenerate(0) = 1.0;
  testExpmap2quat(quat_degenerate);
  quat_degenerate(0) = -1.0;
  testExpmap2quat(quat_degenerate);
  for (int i = 0; i<ntests; i++)
  {
    Vector4d quat = uniformlyRandomQuat(generator);
    testExpmap2quat(quat);
  }
  // quat2eigenQuaternion
  Vector4d quat = uniformlyRandomQuat(generator);
  Quaterniond eigenQuat = quat2eigenQuaternion(quat);
  Matrix3d R_expected = quat2rotmat(quat);
  Matrix3d R_eigen = eigenQuat.matrix();
  valuecheckMatrix(R_expected, R_eigen, 1e-6);
}

void testDHomogTrans(int ntests) {
  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3));
    //  T.setIdentity();
    //  T = AngleAxisd(M_PI_2, Vector3d(1.0, 0.0, 0.0));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
//    setLinearIndices(S);
//    S.setIdentity();
//    std::cout << S << "\n\n";

    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
//    setLinearIndices(qdot_to_v);
//    std::cout << qdot_to_v << "\n\n";

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    volatile auto vol = dT;
    //  std::cout << dT << std::endl << std::endl;
  }
}

void testDHomogTransInv(int ntests, bool check) {
  Isometry3d T;
  std::default_random_engine generator;
  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
//    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    T = Quaterniond(q(0), q(1), q(2), q(3));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto dTInv = dHomogTransInv(T, dT);
    volatile auto vol = dTInv;

    if (check) {
      auto dTInvInv = dHomogTransInv(T.inverse(), dTInv);

      if (!dT.matrix().isApprox(dTInvInv.matrix(), 1e-10)) {
        std::cout << "dTInv:\n" << dTInv << "\n\n";
        std::cout << "dT:\n" << dT << "\n\n";
        std::cout << "dTInvInv:\n" << dTInvInv << "\n\n";
        std::cout << "dTInvInv - dT:\n" << dTInvInv - dT << "\n\n";

        throw std::runtime_error("wrong");
      }
    }
  }
}

void testDTransformAdjoint(int ntests) {
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
//    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdT_times_X = dTransformSpatialMotion(T, X, dT, dX).eval();
    volatile auto vol = dAdT_times_X;
  }
}

void testDTransformAdjointTranspose(int ntests) {
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
//    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdTtranspose_times_X = dTransformSpatialForce(T, X, dT, dX).eval();
    volatile auto vol = dAdTtranspose_times_X;
  }
}

void testNormalizeVec(int ntests) {
  const int x_rows = 4;

  for (int testnr = 0; testnr < ntests; testnr++) {
    auto x = Matrix<double, x_rows, 1>::Random().eval();
    Matrix<double, x_rows, 1> x_norm;
    Matrix<double, x_rows, x_rows> dx_norm;
    Matrix<double, x_rows * x_rows, x_rows> ddx_norm;
    normalizeVec(x, x_norm, &dx_norm, &ddx_norm);
//    std::cout << "gradientNumRows: " << gradientNumRows(x_rows, x_rows, 1) << std::endl;

    volatile auto volx_norm = x_norm;
    volatile auto voldx_norm = dx_norm;
    volatile auto volddx_norm = ddx_norm;

//    std::cout << "x_norm:\n" << x_norm << std::endl << std::endl;
//    std::cout << "dx_norm:\n" << dx_norm << std::endl << std::endl;
//    std::cout << "ddx_norm:\n" << ddx_norm << std::endl << std::endl;
  }
}

void testSpatialCrossProduct()
{
  auto a = (Matrix<double, TWIST_SIZE, 1>::Random()).eval();
  auto b = (Matrix<double, TWIST_SIZE, TWIST_SIZE>::Identity()).eval();
  auto a_crm_b = crossSpatialMotion(a, b);
  auto a_crf_b = crossSpatialForce(a, b);
  valuecheckMatrix(a_crf_b, -a_crm_b.transpose(), 1e-8);
}

void testdrpy2rotmat()
{
  default_random_engine generator;
  Vector3d rpy = uniformlyRandomRPY(generator);
  Matrix3d R = rpy2rotmat(rpy);
  Matrix<double,9,3> dR = drpy2rotmat(rpy);
  Matrix<double,9,3> dR_num = Matrix<double,9,3>::Zero();
  for(int i = 0;i<3;i++)
  {
    Vector3d err = Vector3d::Zero();
    err(i) = 1e-7;
    Vector3d rpyi = rpy+err;
    Matrix3d Ri = rpy2rotmat(rpyi);
    Matrix3d Ri_err = (Ri-R)/err(i);
    for(int j = 0;j<9;j++)
    {
      dR_num(j,i) = Ri_err(j);
      valuecheck(dR(j,i),dR_num(j,i),1e-3);
    }
  }
}

void testExpmap2quat(const Vector4d &quat)
{
  auto quat_autodiff = initializeAutoDiff(quat);
  auto expmap_autodiff = quat2expmap(quat_autodiff);
  auto quat_back_autodiff  = expmap2quat(expmap_autodiff);
  auto quat_back = autoDiffToValueMatrix(quat_back_autodiff);
  valuecheck(std::abs((quat.transpose() * quat_back).value()), 1.0, 1e-8);
  Matrix3d identity = Matrix3d::Identity();
  valuecheckMatrix((autoDiffToGradientMatrix(expmap_autodiff) * autoDiffToGradientMatrix(quat_back_autodiff)).eval(), identity, 1E-10);
}

int main(int argc, char **argv)
{
  testRotationConversionFunctions();

  int ntests = 100000;
  std::cout << "testDHomogTrans elapsed time: " << measure<>::execution(testDHomogTrans, ntests) << std::endl;
  std::cout << "testDHomogTransInv elapsed time: " << measure<>::execution(testDHomogTransInv, ntests, false) << std::endl;
  std::cout << "testDTransformAdjoint elapsed time: " << measure<>::execution(testDTransformAdjoint, ntests) << std::endl;
  std::cout << "testDTransformAdjointTranspose elapsed time: " << measure<>::execution(testDTransformAdjointTranspose, ntests) << std::endl;
  std::cout << "testNormalizeVec elapsed time: " << measure<>::execution(testNormalizeVec, ntests) << std::endl;

  testDHomogTransInv(1000, true);
  testSpatialCrossProduct();
	testdrpy2rotmat();

  return 0;
}
<commit_msg>Fix testDrakeGeometryUtil.<commit_after>#include <Eigen/Core>
#include "drake/util/drakeGeometryUtil.h"
#include "drake/util/testUtil.h"
#include "drake/core/Gradient.h"
#include <iostream>
#include <cmath>

using namespace Eigen;
using namespace std;
using namespace Drake;

void testExpmap2quat(const Vector4d &quat);

void testRotationConversionFunctions()
{
  int ntests = 100;
  default_random_engine generator;
  // quat2axis, axis2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    auto a = quat2axis(q);
    auto q_back = axis2quat(a);
    valuecheck(acos(abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rotmat, rotmat2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Matrix3d R = quat2rotmat(q);
    Vector4d q_back = rotmat2quat(R);
    valuecheck(acos(abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // quat2rpy, rpy2quat
  for (int i = 0; i < ntests; i++) {
    Vector4d q = uniformlyRandomQuat(generator);
    Vector3d rpy = quat2rpy(q);
    Vector4d q_back = rpy2quat(rpy);
    valuecheck(acos(abs(q.transpose() * q_back)), 0.0, 1e-6);
  }
  // rotmat2axis, axis2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector4d a = rotmat2axis(R);
    Matrix3d R_back = axis2rotmat(a);
    valuecheckMatrix(R, R_back, 1e-6);
  }
  // rotmat2rpy, rpy2rotmat
  for (int i = 0; i < ntests; i++) {
    Matrix3d R = uniformlyRandomRotmat(generator);
    Vector3d rpy = rotmat2rpy(R);
    Matrix3d R_back = rpy2rotmat(rpy);
    valuecheckMatrix(R, R_back, 1e-6);
  }
  // rpy2axis, axis2rpy
  for (int i = 0; i < ntests; i++) {
    Vector3d rpy = uniformlyRandomRPY(generator);
    Vector4d axis = rpy2axis(rpy);
    Vector3d rpy_back = axis2rpy(axis);
    valuecheckMatrix(rpy, rpy_back, 1e-6);
  }
  // expmap2quat, quat2expmap
  Vector4d quat_degenerate = Vector4d::Zero();
  quat_degenerate(0) = 1.0;
  testExpmap2quat(quat_degenerate);
  quat_degenerate(0) = -1.0;
  testExpmap2quat(quat_degenerate);
  for (int i = 0; i<ntests; i++)
  {
    Vector4d quat = uniformlyRandomQuat(generator);
    testExpmap2quat(quat);
  }
  // quat2eigenQuaternion
  Vector4d quat = uniformlyRandomQuat(generator);
  Quaterniond eigenQuat = quat2eigenQuaternion(quat);
  Matrix3d R_expected = quat2rotmat(quat);
  Matrix3d R_eigen = eigenQuat.matrix();
  valuecheckMatrix(R_expected, R_eigen, 1e-6);
}

void testDHomogTrans(int ntests) {
  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3));
    //  T.setIdentity();
    //  T = AngleAxisd(M_PI_2, Vector3d(1.0, 0.0, 0.0));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
//    setLinearIndices(S);
//    S.setIdentity();
//    std::cout << S << "\n\n";

    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
//    setLinearIndices(qdot_to_v);
//    std::cout << qdot_to_v << "\n\n";

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    volatile auto vol = dT;
    //  std::cout << dT << std::endl << std::endl;
  }
}

void testDHomogTransInv(int ntests, bool check) {
  Isometry3d T;
  std::default_random_engine generator;
  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
//    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    T = Quaterniond(q(0), q(1), q(2), q(3));

    const int nv = 6;
    const int nq = 7;

    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();

    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto dTInv = dHomogTransInv(T, dT);
    volatile auto vol = dTInv;

    if (check) {
      auto dTInvInv = dHomogTransInv(T.inverse(), dTInv);

      if (!dT.matrix().isApprox(dTInvInv.matrix(), 1e-10)) {
        std::cout << "dTInv:\n" << dTInv << "\n\n";
        std::cout << "dT:\n" << dT << "\n\n";
        std::cout << "dTInvInv:\n" << dTInvInv << "\n\n";
        std::cout << "dTInvInv - dT:\n" << dTInvInv - dT << "\n\n";

        throw std::runtime_error("wrong");
      }
    }
  }
}

void testDTransformAdjoint(int ntests) {
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
//    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdT_times_X = dTransformSpatialMotion(T, X, dT, dX).eval();
    volatile auto vol = dAdT_times_X;
  }
}

void testDTransformAdjointTranspose(int ntests) {
  const int nv = 6;
  const int nq = 34;
  const int cols_X = 3;

  Isometry3d T;
  std::default_random_engine generator;

  for (int testnr = 0; testnr < ntests; testnr++) {
    Vector4d q = uniformlyRandomQuat(generator);
    T = Quaterniond(q(0), q(1), q(2), q(3)) * Translation3d(Vector3d::Random());
    auto S = Matrix<double, 6, Dynamic>::Random(6, nv).eval();
    auto qdot_to_v = MatrixXd::Random(nv, nq).eval();
    auto dT = dHomogTrans(T, S, qdot_to_v).eval();
    auto X = Matrix<double, 6, Dynamic>::Random(6, cols_X).eval();
    auto dX = MatrixXd::Random(X.size(), nq).eval();
//    auto dX = Matrix<double, X.SizeAtCompileTime, nq>::Random().eval();
    auto dAdTtranspose_times_X = dTransformSpatialForce(T, X, dT, dX).eval();
    volatile auto vol = dAdTtranspose_times_X;
  }
}

void testNormalizeVec(int ntests) {
  const int x_rows = 4;

  for (int testnr = 0; testnr < ntests; testnr++) {
    auto x = Matrix<double, x_rows, 1>::Random().eval();
    Matrix<double, x_rows, 1> x_norm;
    Matrix<double, x_rows, x_rows> dx_norm;
    Matrix<double, x_rows * x_rows, x_rows> ddx_norm;
    normalizeVec(x, x_norm, &dx_norm, &ddx_norm);
//    std::cout << "gradientNumRows: " << gradientNumRows(x_rows, x_rows, 1) << std::endl;

    volatile auto volx_norm = x_norm;
    volatile auto voldx_norm = dx_norm;
    volatile auto volddx_norm = ddx_norm;

//    std::cout << "x_norm:\n" << x_norm << std::endl << std::endl;
//    std::cout << "dx_norm:\n" << dx_norm << std::endl << std::endl;
//    std::cout << "ddx_norm:\n" << ddx_norm << std::endl << std::endl;
  }
}

void testSpatialCrossProduct()
{
  auto a = (Matrix<double, TWIST_SIZE, 1>::Random()).eval();
  auto b = (Matrix<double, TWIST_SIZE, TWIST_SIZE>::Identity()).eval();
  auto a_crm_b = crossSpatialMotion(a, b);
  auto a_crf_b = crossSpatialForce(a, b);
  valuecheckMatrix(a_crf_b, -a_crm_b.transpose(), 1e-8);
}

void testdrpy2rotmat()
{
  default_random_engine generator;
  Vector3d rpy = uniformlyRandomRPY(generator);
  Matrix3d R = rpy2rotmat(rpy);
  Matrix<double,9,3> dR = drpy2rotmat(rpy);
  Matrix<double,9,3> dR_num = Matrix<double,9,3>::Zero();
  for(int i = 0;i<3;i++)
  {
    Vector3d err = Vector3d::Zero();
    err(i) = 1e-7;
    Vector3d rpyi = rpy+err;
    Matrix3d Ri = rpy2rotmat(rpyi);
    Matrix3d Ri_err = (Ri-R)/err(i);
    for(int j = 0;j<9;j++)
    {
      dR_num(j,i) = Ri_err(j);
      valuecheck(dR(j,i),dR_num(j,i),1e-3);
    }
  }
}

void testExpmap2quat(const Vector4d &quat)
{
  auto quat_autodiff = initializeAutoDiff(quat);
  auto expmap_autodiff = quat2expmap(quat_autodiff);
  auto expmap = autoDiffToValueMatrix(expmap_autodiff);
  auto expmap_grad = autoDiffToGradientMatrix(expmap_autodiff);
  auto quat_back_autodiff  = expmap2quat(initializeAutoDiff(expmap));
  auto quat_back = autoDiffToValueMatrix(quat_back_autodiff);
  auto quat_back_grad = autoDiffToGradientMatrix(quat_back_autodiff);
  valuecheck(std::abs((quat.transpose() * quat_back).value()), 1.0, 1e-8);
  Matrix3d identity = Matrix3d::Identity();
  valuecheckMatrix((expmap_grad * quat_back_grad).eval(), identity, 1E-10);
}

int main(int argc, char **argv)
{
  testRotationConversionFunctions();

  int ntests = 100000;
  std::cout << "testDHomogTrans elapsed time: " << measure<>::execution(testDHomogTrans, ntests) << std::endl;
  std::cout << "testDHomogTransInv elapsed time: " << measure<>::execution(testDHomogTransInv, ntests, false) << std::endl;
  std::cout << "testDTransformAdjoint elapsed time: " << measure<>::execution(testDTransformAdjoint, ntests) << std::endl;
  std::cout << "testDTransformAdjointTranspose elapsed time: " << measure<>::execution(testDTransformAdjointTranspose, ntests) << std::endl;
  std::cout << "testNormalizeVec elapsed time: " << measure<>::execution(testNormalizeVec, ntests) << std::endl;

  testDHomogTransInv(1000, true);
  testSpatialCrossProduct();
	testdrpy2rotmat();

  return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <vector>
#include <string>
#include <cmath>
#include <map>
#include <fstream>

#include <utils.hpp>
#include <Observation.hpp>

#ifndef SNR_HPP
#define SNR_HPP

namespace PulsarSearch {

class snrConf {
public:
  snrConf();
  ~snrConf();
  // Get
  unsigned int getNrThreadsD0() const;
  unsigned int getNrItemsD0() const;
  // Set
  void setNrThreadsD0(unsigned int threads);
  void setNrItemsD0(unsigned int items);
  // utils
  std::string print() const;

private:
  unsigned int nrThreadsD0;
  unsigned int nrItemsD0;
};

typedef std::map< std::string, std::map< unsigned int, std::map< unsigned int, PulsarSearch::snrConf * > * > * > tunedSNRConf;

// OpenCL SNR
template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding);
template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding);
// Read configuration files
void readTunedSNRConf(tunedSNRConf & tunedSNR, const std::string & snrFilename);

// Implementations
inline unsigned int snrConf::getNrThreadsD0() const {
  return nrThreadsD0;
}

inline unsigned int snrConf::getNrItemsD0() const {
  return nrItemsD0;
}

inline void snrConf::setNrThreadsD0(unsigned int threads) {
  nrThreadsD0 = threads;
}

inline void snrConf::setNrItemsD0(unsigned int items) {
  nrItemsD0 = items;
}

template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrDMsSamples" + isa::utils::toString(nrSamples) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = get_group_id(1);\n"
    "float delta = 0.0f;\n"
    "__local float reductionCOU[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local " + dataName + " reductionMAX[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionMEA[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionVAR[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "<%DEF%>"
    "\n"
    "// Compute phase\n"
    "for ( unsigned int sample = get_local_id(0) + " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + "; sample < " + isa::utils::toString(nrSamples) + "; sample += " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + " ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "// In-thread reduce\n"
    "<%REDUCE%>"
    "// Local memory store\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "// Reduce phase\n"
    "unsigned int threshold = " + isa::utils::toString(conf.getNrThreadsD0() / 2) + ";\n"
    "for ( unsigned int sample = get_local_id(0); threshold > 0; threshold /= 2 ) {\n"
    "if ( sample < threshold ) {\n"
    "delta = reductionMEA[sample + threshold] - mean0;\n"
    "counter0 += reductionCOU[sample + threshold];\n"
    "max0 = fmax(max0, reductionMAX[sample + threshold]);\n"
    "mean0 = ((reductionCOU[sample] * mean0) + (reductionCOU[sample + threshold] * reductionMEA[sample + threshold])) / counter0;\n"
    "variance0 += reductionVAR[sample + threshold] + ((delta * delta) * ((reductionCOU[sample] * reductionCOU[sample + threshold]) / counter0));\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "}\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "}\n"
    "// Store\n"
    "if ( get_local_id(0) == 0 ) {\n"
    "output[dm] = (max0 - mean0) / native_sqrt(variance0 * " + isa::utils::toString(1.0f / (nrSamples - 1)) + "f);\n"
    "}\n"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (get_local_id(0) + <%OFFSET%>)];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "item = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (sample + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n";
  std::string reduce_sTemplate = "delta = mean<%NUM%> - mean0;\n"
    "counter0 += counter<%NUM%>;\n"
    "max0 = fmax(max0, max<%NUM%>);\n"
    "mean0 = (((counter0 - counter<%NUM%>) * mean0) + (counter<%NUM%> * mean<%NUM%>)) / counter0;\n"
    "variance0 += variance<%NUM%> + ((delta * delta) * (((counter0 - counter<%NUM%>) * counter<%NUM%>) / counter0));\n";
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * reduce_s = new std::string();

  for ( unsigned int sample = 0; sample < conf.getNrItemsD0(); sample++ ) {
    std::string sample_s = isa::utils::toString(sample);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * sample);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    if ( sample == 0 ) {
      continue;
    }
    temp = isa::utils::replace(&reduce_sTemplate, "<%NUM%>", sample_s);
    reduce_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%REDUCE%>", *reduce_s, true);
  delete def_s;
  delete compute_s;
  delete reduce_s;

  return code;
}

template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrSamplesDMs" + isa::utils::toString(observation.getNrDMs()) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = (" + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0);\n"
    "<%DEF%>"
    "\n"
    "for ( unsigned int sample = 1; sample < " + isa::utils::toString(observation.getNrSamplesPerSecond()) + "; sample++ ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "<%STORE%>"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[dm + <%OFFSET%>];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "item = input[(sample * " + isa::utils::toString(observation.getNrPaddedDMs(padding / sizeof(T))) + "  + (dm + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n";
  std::string store_sTemplate;
  if ( dataName == "double" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0 / (nrSamples - 1)) + ");\n";
  } else if ( dataName == "float" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0f / (nrSamples - 1)) + "f);\n";
  } else {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> / " + isa::utils::toString(observation.getNrSamplesPerSecond() - 1) + "f);\n";
  }
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * store_s = new std::string();

  for ( unsigned int dm = 0; dm < conf.getNrItemsD0(); dm++ ) {
    std::string dm_s = isa::utils::toString(dm);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * dm);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&store_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    store_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%STORE%>", *store_s, true);
  delete def_s;
  delete compute_s;
  delete store_s;

  return code;
}

} // PulsarSearch

#endif // SNR_HPP

<commit_msg>Typo.<commit_after>// Copyright 2014 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <vector>
#include <string>
#include <cmath>
#include <map>
#include <fstream>

#include <utils.hpp>
#include <Observation.hpp>

#ifndef SNR_HPP
#define SNR_HPP

namespace PulsarSearch {

class snrConf {
public:
  snrConf();
  ~snrConf();
  // Get
  unsigned int getNrThreadsD0() const;
  unsigned int getNrItemsD0() const;
  // Set
  void setNrThreadsD0(unsigned int threads);
  void setNrItemsD0(unsigned int items);
  // utils
  std::string print() const;

private:
  unsigned int nrThreadsD0;
  unsigned int nrItemsD0;
};

typedef std::map< std::string, std::map< unsigned int, std::map< unsigned int, PulsarSearch::snrConf * > * > * > tunedSNRConf;

// OpenCL SNR
template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding);
template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding);
// Read configuration files
void readTunedSNRConf(tunedSNRConf & tunedSNR, const std::string & snrFilename);

// Implementations
inline unsigned int snrConf::getNrThreadsD0() const {
  return nrThreadsD0;
}

inline unsigned int snrConf::getNrItemsD0() const {
  return nrItemsD0;
}

inline void snrConf::setNrThreadsD0(unsigned int threads) {
  nrThreadsD0 = threads;
}

inline void snrConf::setNrItemsD0(unsigned int items) {
  nrItemsD0 = items;
}

template< typename T > std::string * getSNRDMsSamplesOpenCL(const snrConf & conf, const std::string & dataName, const unsigned int nrSamples, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrDMsSamples" + isa::utils::toString(nrSamples) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = get_group_id(1);\n"
    "float delta = 0.0f;\n"
    "__local float reductionCOU[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local " + dataName + " reductionMAX[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionMEA[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "__local float reductionVAR[" + isa::utils::toString(isa::utils::pad(conf.getNrThreadsD0(), padding / sizeof(T))) + "];\n"
    "<%DEF%>"
    "\n"
    "// Compute phase\n"
    "for ( unsigned int sample = get_local_id(0) + " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + "; sample < " + isa::utils::toString(nrSamples) + "; sample += " + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + " ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "// In-thread reduce\n"
    "<%REDUCE%>"
    "// Local memory store\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "// Reduce phase\n"
    "unsigned int threshold = " + isa::utils::toString(conf.getNrThreadsD0() / 2) + ";\n"
    "for ( unsigned int sample = get_local_id(0); threshold > 0; threshold /= 2 ) {\n"
    "if ( sample < threshold ) {\n"
    "delta = reductionMEA[sample + threshold] - mean0;\n"
    "counter0 += reductionCOU[sample + threshold];\n"
    "max0 = fmax(max0, reductionMAX[sample + threshold]);\n"
    "mean0 = ((reductionCOU[sample] * mean0) + (reductionCOU[sample + threshold] * reductionMEA[sample + threshold])) / counter0;\n"
    "variance0 += reductionVAR[sample + threshold] + ((delta * delta) * ((reductionCOU[sample] * reductionCOU[sample + threshold]) / counter0));\n"
    "reductionCOU[get_local_id(0)] = counter0;\n"
    "reductionMAX[get_local_id(0)] = max0;\n"
    "reductionMEA[get_local_id(0)] = mean0;\n"
    "reductionVAR[get_local_id(0)] = variance0;\n"
    "}\n"
    "barrier(CLK_LOCAL_MEM_FENCE);\n"
    "}\n"
    "// Store\n"
    "if ( get_local_id(0) == 0 ) {\n"
    "output[dm] = (max0 - mean0) / native_sqrt(variance0 * " + isa::utils::toString(1.0f / (nrSamples - 1)) + "f);\n"
    "}\n"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (get_local_id(0) + <%OFFSET%>)];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "item = input[(dm * " + isa::utils::toString(isa::utils::pad(nrSamples, padding / sizeof(T))) + ") + (sample + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n";
  std::string reduce_sTemplate = "delta = mean<%NUM%> - mean0;\n"
    "counter0 += counter<%NUM%>;\n"
    "max0 = fmax(max0, max<%NUM%>);\n"
    "mean0 = (((counter0 - counter<%NUM%>) * mean0) + (counter<%NUM%> * mean<%NUM%>)) / counter0;\n"
    "variance0 += variance<%NUM%> + ((delta * delta) * (((counter0 - counter<%NUM%>) * counter<%NUM%>) / counter0));\n";
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * reduce_s = new std::string();

  for ( unsigned int sample = 0; sample < conf.getNrItemsD0(); sample++ ) {
    std::string sample_s = isa::utils::toString(sample);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * sample);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", sample_s);
    if ( sample == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    if ( sample == 0 ) {
      continue;
    }
    temp = isa::utils::replace(&reduce_sTemplate, "<%NUM%>", sample_s);
    reduce_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%REDUCE%>", *reduce_s, true);
  delete def_s;
  delete compute_s;
  delete reduce_s;

  return code;
}

template< typename T > std::string * getSNRSamplesDMsOpenCL(const snrConf & conf, const std::string & dataName, const AstroData::Observation & observation, const unsigned int padding) {
  std::string * code = new std::string();

  // Begin kernel's template
  *code = "__kernel void snrSamplesDMs" + isa::utils::toString(observation.getNrDMs()) + "(__global const " + dataName + " * const restrict input, __global float * const restrict output) {\n"
    "unsigned int dm = (" + isa::utils::toString(conf.getNrThreadsD0() * conf.getNrItemsD0()) + ") + get_local_id(0);\n"
    "<%DEF%>"
    "\n"
    "for ( unsigned int sample = 1; sample < " + isa::utils::toString(observation.getNrSamplesPerSecond()) + "; sample++ ) {\n"
    + dataName + " item = 0;\n"
    "<%COMPUTE%>"
    "}\n"
    "<%STORE%>"
    "}\n";
  std::string def_sTemplate = "float counter<%NUM%> = 1.0f;\n"
    + dataName + " max<%NUM%> = input[dm + <%OFFSET%>];\n"
    "float variance<%NUM%> = 0.0f;\n"
    "float mean<%NUM%> = max<%NUM%>;\n";
  std::string compute_sTemplate = "item = input[(sample * " + isa::utils::toString(observation.getNrPaddedDMs(padding / sizeof(T))) + "  + (dm + <%OFFSET%>)];\n"
    "counter<%NUM%> += 1.0f;\n"
    "delta = item - mean<%NUM%>;\n"
    "max<%NUM%> = fmax(max<%NUM%>, item);\n"
    "mean<%NUM%> += delta / counter<%NUM%>;\n"
    "variance<%NUM%> += delta * (item - mean<%NUM%>);\n";
  std::string store_sTemplate;
  if ( dataName == "double" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0 / (observation.getNrSamplesPerSecond() - 1)) + ");\n";
  } else if ( dataName == "float" ) {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> * " + isa::utils::toString(1.0f / (observation.getNrSamplesPerSecond() - 1)) + "f);\n";
  } else {
    store_sTemplate = "output[dm + <%OFFSET%>] = (max<%NUM%> - mean<%NUM%>) / native_sqrt(variance<%NUM%> / " + isa::utils::toString(observation.getNrSamplesPerSecond() - 1) + "f);\n";
  }
  // End kernel's template

  std::string * def_s = new std::string();
  std::string * compute_s = new std::string();
  std::string * store_s = new std::string();

  for ( unsigned int dm = 0; dm < conf.getNrItemsD0(); dm++ ) {
    std::string dm_s = isa::utils::toString(dm);
    std::string offset_s = isa::utils::toString(conf.getNrThreadsD0() * dm);
    std::string * temp = 0;

    temp = isa::utils::replace(&def_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    def_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&compute_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    compute_s->append(*temp);
    delete temp;
    temp = isa::utils::replace(&store_sTemplate, "<%NUM%>", dm_s);
    if ( dm == 0 ) {
      std::string empty_s("");
      temp = isa::utils::replace(temp, " + <%OFFSET%>", empty_s, true);
    } else {
      temp = isa::utils::replace(temp, "<%OFFSET%>", offset_s, true);
    }
    store_s->append(*temp);
    delete temp;
  }

  code = isa::utils::replace(code, "<%DEF%>", *def_s, true);
  code = isa::utils::replace(code, "<%COMPUTE%>", *compute_s, true);
  code = isa::utils::replace(code, "<%STORE%>", *store_s, true);
  delete def_s;
  delete compute_s;
  delete store_s;

  return code;
}

} // PulsarSearch

#endif // SNR_HPP

<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <tuple>
#include <utility>

namespace helene
{

namespace soa_detail
{
template <class MemberPointerType>
struct deduce_member_pointer;

template <class MemberType, class ObjectType>
struct deduce_member_pointer<MemberType ObjectType::*>
{
    typedef MemberType member_type;
    typedef ObjectType object_type;
};

template <class MemberPointerType>
using member_type_t =
    typename deduce_member_pointer<MemberPointerType>::member_type;

template <class MemberPointerType>
using object_type_t =
    typename deduce_member_pointer<MemberPointerType>::object_type;
}

template <class PointerType, PointerType PointerValue>
struct member_reference
{
    static constexpr PointerType pointer_value = PointerValue;
};

template <class T, class... MemberRefs>
class element_proxy;

template <class T, class... PointerTypes, PointerTypes... PointerValues>
class element_proxy<T, member_reference<PointerTypes, PointerValues>...>
{
    typedef std::tuple<soa_detail::member_type_t<PointerTypes>*...> tuple_type;

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct assignment_helper
    {
        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*FirstRef::pointer_value;

            assignment_helper<S + 1, RestRefs...>::assign(tpl, value);
        }
    };

    template <std::size_t S, class LastRef>
    struct assignment_helper<S, LastRef>
    {

        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*LastRef::pointer_value;
        }
    };

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct make_helper
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*FirstRef::pointer_value = *std::get<S>(tpl);
            make_helper<S + 1, RestRefs...>::apply(v, tpl);
        }
    };

    template <std::size_t S, class LastRef>
    struct make_helper<S, LastRef>
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*LastRef::pointer_value = *std::get<S>(tpl);
        }
    };

public:
    element_proxy(soa_detail::member_type_t<PointerTypes>&... args)
        : pointers_(&args...)
    {
    }

    operator T() const
    {
        T out{};
        make_helper<0, member_reference<PointerTypes, PointerValues>...>::apply(
            out, pointers_);
        return out;
    }

    element_proxy&
    operator=(const T& value)
    {
        assignment_helper<0, member_reference<PointerTypes, PointerValues>...>::
            assign(pointers_, value);

        return *this;
    }

private:
    tuple_type pointers_;
};

// helper to access respective parents that are multiply inherited
template <class FirstParent, class... RestParents>
struct parent_helper
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.FirstParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.FirstParent::members_.push_back(value.*FirstParent::pointer);
        parent_helper<RestParents...>::push_back(s, value);
    }
};

template <class LastParent>
struct parent_helper<LastParent>
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.LastParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.LastParent::members_.push_back(value.*LastParent::pointer);
    }
};

template <class MemberPointerType, MemberPointerType MemberPointerValue>
class member_container
{
public:
    typedef soa_detail::member_type_t<MemberPointerType> member_type;
    typedef soa_detail::object_type_t<MemberPointerType> object_type;

    static constexpr MemberPointerType pointer = MemberPointerValue;

public:
    member_container() = default;

    std::vector<member_type> members_;
};

template <class T, class... MemberContainer>
class soa;

template <class T, class... MemberPtrTypes, MemberPtrTypes... MemberPtrValues>
class soa<T, member_container<MemberPtrTypes, MemberPtrValues>...>
    : public member_container<MemberPtrTypes, MemberPtrValues>...
{
public:
    typedef T value_type;
    typedef element_proxy<T,
                          member_reference<MemberPtrTypes, MemberPtrValues>...>
        proxy_value_type;

public:
    soa() : member_container<MemberPtrTypes, MemberPtrValues>()...
    {
    }

    std::size_t
    size() const
    {
        return parent_helper<
            member_container<MemberPtrTypes, MemberPtrValues>...>::size(*this);
    }

    void
    push_back(const T& value)
    {
        parent_helper<member_container<MemberPtrTypes, MemberPtrValues>...>::
            push_back(*this, value);
    }

    template <class... Args>
    void emplace_back(Args&&... args)
    {

    }

    proxy_value_type operator[](std::size_t n)
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    const proxy_value_type operator[](std::size_t n) const
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    soa_detail::member_type_t<MemberPtrType>*
    data()
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    const soa_detail::member_type_t<MemberPtrType>*
    data() const
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }
};
}
<commit_msg>Rename static constexpr pointer to pointer_value. 	modified:   include/soa.hpp<commit_after>#pragma once

#include <vector>
#include <tuple>
#include <utility>

namespace helene
{

namespace soa_detail
{
template <class MemberPointerType>
struct deduce_member_pointer;

template <class MemberType, class ObjectType>
struct deduce_member_pointer<MemberType ObjectType::*>
{
    typedef MemberType member_type;
    typedef ObjectType object_type;
};

template <class MemberPointerType>
using member_type_t =
    typename deduce_member_pointer<MemberPointerType>::member_type;

template <class MemberPointerType>
using object_type_t =
    typename deduce_member_pointer<MemberPointerType>::object_type;
}

template <class PointerType, PointerType PointerValue>
struct member_reference
{
    static constexpr PointerType pointer_value = PointerValue;
};

template <class T, class... MemberRefs>
class element_proxy;

template <class T, class... PointerTypes, PointerTypes... PointerValues>
class element_proxy<T, member_reference<PointerTypes, PointerValues>...>
{
    typedef std::tuple<soa_detail::member_type_t<PointerTypes>*...> tuple_type;

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct assignment_helper
    {
        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*FirstRef::pointer_value;

            assignment_helper<S + 1, RestRefs...>::assign(tpl, value);
        }
    };

    template <std::size_t S, class LastRef>
    struct assignment_helper<S, LastRef>
    {

        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*LastRef::pointer_value;
        }
    };

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct make_helper
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*FirstRef::pointer_value = *std::get<S>(tpl);
            make_helper<S + 1, RestRefs...>::apply(v, tpl);
        }
    };

    template <std::size_t S, class LastRef>
    struct make_helper<S, LastRef>
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*LastRef::pointer_value = *std::get<S>(tpl);
        }
    };

public:
    element_proxy(soa_detail::member_type_t<PointerTypes>&... args)
        : pointers_(&args...)
    {
    }

    operator T() const
    {
        T out{};
        make_helper<0, member_reference<PointerTypes, PointerValues>...>::apply(
            out, pointers_);
        return out;
    }

    element_proxy&
    operator=(const T& value)
    {
        assignment_helper<0, member_reference<PointerTypes, PointerValues>...>::
            assign(pointers_, value);

        return *this;
    }

private:
    tuple_type pointers_;
};

// helper to access respective parents that are multiply inherited
template <class FirstParent, class... RestParents>
struct parent_helper
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.FirstParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.FirstParent::members_.push_back(value.*FirstParent::pointer_value);
        parent_helper<RestParents...>::push_back(s, value);
    }
};

template <class LastParent>
struct parent_helper<LastParent>
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.LastParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.LastParent::members_.push_back(value.*LastParent::pointer_value);
    }
};

template <class MemberPointerType, MemberPointerType MemberPointerValue>
class member_container
{
public:
    typedef soa_detail::member_type_t<MemberPointerType> member_type;
    typedef soa_detail::object_type_t<MemberPointerType> object_type;

    static constexpr MemberPointerType pointer_value = MemberPointerValue;

public:
    member_container() = default;

    std::vector<member_type> members_;
};

template <class T, class... MemberContainer>
class soa;

template <class T, class... MemberPtrTypes, MemberPtrTypes... MemberPtrValues>
class soa<T, member_container<MemberPtrTypes, MemberPtrValues>...>
    : public member_container<MemberPtrTypes, MemberPtrValues>...
{
public:
    typedef T value_type;
    typedef element_proxy<T,
                          member_reference<MemberPtrTypes, MemberPtrValues>...>
        proxy_value_type;

public:
    soa() : member_container<MemberPtrTypes, MemberPtrValues>()...
    {
    }

    std::size_t
    size() const
    {
        return parent_helper<
            member_container<MemberPtrTypes, MemberPtrValues>...>::size(*this);
    }

    void
    push_back(const T& value)
    {
        parent_helper<member_container<MemberPtrTypes, MemberPtrValues>...>::
            push_back(*this, value);
    }

    template <class... Args>
    void emplace_back(Args&&... args)
    {

    }

    proxy_value_type operator[](std::size_t n)
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    const proxy_value_type operator[](std::size_t n) const
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    soa_detail::member_type_t<MemberPtrType>*
    data()
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    const soa_detail::member_type_t<MemberPtrType>*
    data() const
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }
};
}
<|endoftext|>


<commit_before>#include "catch.hpp"

#include "ReverseInteger.hpp"

TEST_CASE("Reverse Integer") {
  Solution s;

  SECTION("Sample test") {
    REQUIRE(s.reverse(123) == 321);
    REQUIRE(s.reverse(-123) == -321);
  }
}
<commit_msg>Update Problem 7 test case<commit_after>#include "catch.hpp"

#include "ReverseInteger.hpp"

TEST_CASE("Reverse Integer") {
  Solution s;

  SECTION("Sample test") {
    REQUIRE(s.reverse(123) == 321);
    REQUIRE(s.reverse(-123) == -321);
  }

  SECTION("Overflow test") {
    REQUIRE(s.reverse(-2147483648) == 0);
    REQUIRE(s.reverse(2147483647) == 0);
  }

  SECTION("Leading zeros test") {
    REQUIRE(s.reverse(1234000) == 4321);
    REQUIRE(s.reverse(-1234000) == -4321);
  }
}
<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <tuple>
#include <utility>

namespace helene
{

namespace soa_detail
{
template <class MemberPointerType>
struct deduce_member_pointer;

template <class MemberType, class ObjectType>
struct deduce_member_pointer<MemberType ObjectType::*>
{
    typedef MemberType member_type;
    typedef ObjectType object_type;
};

template <class MemberPointerType>
using member_type_t =
    typename deduce_member_pointer<MemberPointerType>::member_type;

template <class MemberPointerType>
using object_type_t =
    typename deduce_member_pointer<MemberPointerType>::object_type;
}

template <class PointerType, PointerType PointerValue>
struct member_reference
{
    static constexpr PointerType pointer_value = PointerValue;
};

template <class T, class... MemberRefs>
class element_proxy;

template <class T, class... PointerTypes, PointerTypes... PointerValues>
class element_proxy<T, member_reference<PointerTypes, PointerValues>...>
{
    typedef std::tuple<soa_detail::member_type_t<PointerTypes>*...> tuple_type;

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct assignment_helper
    {
        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*FirstRef::pointer_value;

            assignment_helper<S + 1, RestRefs...>::assign(tpl, value);
        }
    };

    template <std::size_t S, class LastRef>
    struct assignment_helper<S, LastRef>
    {

        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*LastRef::pointer_value;
        }
    };

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct make_helper
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*FirstRef::pointer_value = *std::get<S>(tpl);
            make_helper<S + 1, RestRefs...>::apply(v, tpl);
        }
    };

    template <std::size_t S, class LastRef>
    struct make_helper<S, LastRef>
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*LastRef::pointer_value = *std::get<S>(tpl);
        }
    };

public:
    element_proxy(soa_detail::member_type_t<PointerTypes>&... args)
        : pointers_(&args...)
    {
    }

    operator T() const
    {
        T out{};
        make_helper<0, member_reference<PointerTypes, PointerValues>...>::apply(
            out, pointers_);
        return out;
    }

    element_proxy&
    operator=(const T& value)
    {
        assignment_helper<0, member_reference<PointerTypes, PointerValues>...>::
            assign(pointers_, value);

        return *this;
    }

private:
    tuple_type pointers_;
};

// helper to access respective parents that are multiply inherited
template <class FirstParent, class... RestParents>
struct parent_helper
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.FirstParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.FirstParent::members_.push_back(value.*FirstParent::pointer_value);
        parent_helper<RestParents...>::push_back(s, value);
    }
};

template <class LastParent>
struct parent_helper<LastParent>
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.LastParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.LastParent::members_.push_back(value.*LastParent::pointer_value);
    }
};

template <class MemberPointerType, MemberPointerType MemberPointerValue>
class member_container
{
public:
    typedef soa_detail::member_type_t<MemberPointerType> member_type;
    typedef soa_detail::object_type_t<MemberPointerType> object_type;

    static constexpr MemberPointerType pointer_value = MemberPointerValue;

public:
    member_container() = default;

    std::vector<member_type> members_;
};

template <class T, class... MemberContainer>
class soa;

template <class T, class... MemberPtrTypes, MemberPtrTypes... MemberPtrValues>
class soa<T, member_container<MemberPtrTypes, MemberPtrValues>...>
    : public member_container<MemberPtrTypes, MemberPtrValues>...
{
public:
    typedef T value_type;
    typedef element_proxy<T,
                          member_reference<MemberPtrTypes, MemberPtrValues>...>
        proxy_value_type;

public:
    soa() : member_container<MemberPtrTypes, MemberPtrValues>()...
    {
    }

    std::size_t
    size() const
    {
        return parent_helper<
            member_container<MemberPtrTypes, MemberPtrValues>...>::size(*this);
    }

    void
    push_back(const T& value)
    {
        parent_helper<member_container<MemberPtrTypes, MemberPtrValues>...>::
            push_back(*this, value);
    }

    template <class... Args>
    void emplace_back(Args&&... args)
    {

    }

    proxy_value_type operator[](std::size_t n)
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    const proxy_value_type operator[](std::size_t n) const
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    soa_detail::member_type_t<MemberPtrType>*
    data()
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    const soa_detail::member_type_t<MemberPtrType>*
    data() const
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }
};
}
<commit_msg>Decide against emplace_back. 	modified:   include/soa.hpp<commit_after>#pragma once

#include <vector>
#include <tuple>
#include <utility>

namespace helene
{

namespace soa_detail
{
template <class MemberPointerType>
struct deduce_member_pointer;

template <class MemberType, class ObjectType>
struct deduce_member_pointer<MemberType ObjectType::*>
{
    typedef MemberType member_type;
    typedef ObjectType object_type;
};

template <class MemberPointerType>
using member_type_t =
    typename deduce_member_pointer<MemberPointerType>::member_type;

template <class MemberPointerType>
using object_type_t =
    typename deduce_member_pointer<MemberPointerType>::object_type;
}

template <class PointerType, PointerType PointerValue>
struct member_reference
{
    static constexpr PointerType pointer_value = PointerValue;
};

template <class T, class... MemberRefs>
class element_proxy;

template <class T, class... PointerTypes, PointerTypes... PointerValues>
class element_proxy<T, member_reference<PointerTypes, PointerValues>...>
{
    typedef std::tuple<soa_detail::member_type_t<PointerTypes>*...> tuple_type;

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct assignment_helper
    {
        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*FirstRef::pointer_value;

            assignment_helper<S + 1, RestRefs...>::assign(tpl, value);
        }
    };

    template <std::size_t S, class LastRef>
    struct assignment_helper<S, LastRef>
    {

        static void
        assign(std::tuple<soa_detail::member_type_t<PointerTypes>*...>& tpl,
               const T& value)
        {
            *std::get<S>(tpl) = value.*LastRef::pointer_value;
        }
    };

    template <std::size_t S, class FirstRef, class... RestRefs>
    struct make_helper
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*FirstRef::pointer_value = *std::get<S>(tpl);
            make_helper<S + 1, RestRefs...>::apply(v, tpl);
        }
    };

    template <std::size_t S, class LastRef>
    struct make_helper<S, LastRef>
    {
        static void
        apply(T& v, const tuple_type& tpl)
        {
            v.*LastRef::pointer_value = *std::get<S>(tpl);
        }
    };

public:
    element_proxy(soa_detail::member_type_t<PointerTypes>&... args)
        : pointers_(&args...)
    {
    }

    operator T() const
    {
        T out{};
        make_helper<0, member_reference<PointerTypes, PointerValues>...>::apply(
            out, pointers_);
        return out;
    }

    element_proxy&
    operator=(const T& value)
    {
        assignment_helper<0, member_reference<PointerTypes, PointerValues>...>::
            assign(pointers_, value);

        return *this;
    }

private:
    tuple_type pointers_;
};

// helper to access respective parents that are multiply inherited
template <class FirstParent, class... RestParents>
struct parent_helper
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.FirstParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.FirstParent::members_.push_back(value.*FirstParent::pointer_value);
        parent_helper<RestParents...>::push_back(s, value);
    }
};

template <class LastParent>
struct parent_helper<LastParent>
{
    template <class SoaType>
    static std::size_t
    size(const SoaType& s)
    {
        return s.LastParent::members_.size();
    }

    template <class SoaType>
    static void
    push_back(SoaType& s, const typename SoaType::value_type& value)
    {
        s.LastParent::members_.push_back(value.*LastParent::pointer_value);
    }
};

template <class MemberPointerType, MemberPointerType MemberPointerValue>
class member_container
{
public:
    typedef soa_detail::member_type_t<MemberPointerType> member_type;
    typedef soa_detail::object_type_t<MemberPointerType> object_type;

    static constexpr MemberPointerType pointer_value = MemberPointerValue;

public:
    member_container() = default;

    std::vector<member_type> members_;
};

template <class T, class... MemberContainer>
class soa;

template <class T, class... MemberPtrTypes, MemberPtrTypes... MemberPtrValues>
class soa<T, member_container<MemberPtrTypes, MemberPtrValues>...>
    : public member_container<MemberPtrTypes, MemberPtrValues>...
{
public:
    typedef T value_type;
    typedef element_proxy<T,
                          member_reference<MemberPtrTypes, MemberPtrValues>...>
        proxy_value_type;

public:
    soa() : member_container<MemberPtrTypes, MemberPtrValues>()...
    {
    }

    std::size_t
    size() const
    {
        return parent_helper<
            member_container<MemberPtrTypes, MemberPtrValues>...>::size(*this);
    }

    void
    push_back(const T& value)
    {
        parent_helper<member_container<MemberPtrTypes, MemberPtrValues>...>::
            push_back(*this, value);
    }

    proxy_value_type operator[](std::size_t n)
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    const proxy_value_type operator[](std::size_t n) const
    {
        return proxy_value_type(
            member_container<MemberPtrTypes, MemberPtrValues>::members_[n]...);
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    soa_detail::member_type_t<MemberPtrType>*
    data()
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }

    template <class MemberPtrType, MemberPtrType MemberPtrValue>
    const soa_detail::member_type_t<MemberPtrType>*
    data() const
    {
        return member_container<MemberPtrType, MemberPtrValue>::members_.data();
    }
};
}
<|endoftext|>