<commit_before>#include "Wren++.h"
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cassert>

// a small class to test class & method binding with
struct Vec3
{
    float x, y, z;

    Vec3(float x, float y, float z) : x{x}, y{y}, z{z} {}

    Vec3(const Vec3&) = default;

    float norm() const { return std::sqrt(x * x + y * y + z * z); }

    float dot(const Vec3& rhs) const { return x * rhs.x + y * rhs.y + z * rhs.z; }

    Vec3 cross(const Vec3& rhs) const
    {
        return Vec3{y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x};
    }

    Vec3 plus(const Vec3& rhs) const { return Vec3{x + rhs.x, y + rhs.y, z + rhs.z}; }
};

struct Transform
{
    Transform(const Vec3& p) : position(p) {}

    Vec3 position{0.f, 0.f, 0.f};
};

void CFunctionVectorReference(WrenVM* vm)
{
    static Vec3 v{2.0, 1.0, 1.0};
    wrenpp::setSlotForeignPtr(vm, 0, &v);
}

Vec3* returnVec3Ptr()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return &v;
}

Vec3& returnVec3Ref()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return v;
}

const Vec3* returnVec3ConstPtr()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return &v;
}

const Vec3& returnVec3ConstRef()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return v;
}

void bindVectorModule(wrenpp::VM& vm)
{
    vm.beginModule("vector")
        .bindClass<Vec3, float, float, float>("Vec3")
        .bindGetter<decltype(Vec3::x), &Vec3::x>("x")
        .bindSetter<decltype(Vec3::x), &Vec3::x>("x=(_)")
        .bindGetter<decltype(Vec3::y), &Vec3::y>("y")
        .bindSetter<decltype(Vec3::y), &Vec3::y>("y=(_)")
        .bindGetter<decltype(Vec3::z), &Vec3::z>("z")
        .bindSetter<decltype(Vec3::z), &Vec3::z>("z=(_)")
        .bindMethod<decltype(&Vec3::norm), &Vec3::norm>(false, "norm()")
        .bindMethod<decltype(&Vec3::dot), &Vec3::dot>(false, "dot(_)")
        .bindMethod<decltype(&Vec3::plus), &Vec3::plus>(false, "plus(_)")
        .endClass()
        .endModule();
    vm.beginModule("main")
        .beginClass("VectorReferences")
        .bindCFunction(true, "getCFunction()", CFunctionVectorReference)
        .bindFunction<decltype(&returnVec3Ptr), &returnVec3Ptr>(true, "getPtr()")
        .bindFunction<decltype(&returnVec3Ref), &returnVec3Ref>(true, "getRef()")
        .bindFunction<decltype(&returnVec3ConstPtr), &returnVec3ConstPtr>(true, "getConstPtr()")
        .bindFunction<decltype(&returnVec3ConstRef), returnVec3ConstRef>(true, "getConstRef()")
        .endClass()
        .endModule();
}

void bindTransformModule(wrenpp::VM& vm)
{
    vm.beginModule("transform")
        .bindClass<Transform, Vec3>("Transform")
        .bindSetter<decltype(Transform::position), &Transform::position>("position=(_)")
        .bindGetter<decltype(Transform::position), &Transform::position>("position");
}

void testMethodCall()
{
    wrenpp::VM wren{};

    wren.executeModule("test_method");
    auto passNum = wren.method("main", "passNumber", "call(_)");
    passNum(5.0);
    passNum(5.f);
    passNum(5);
    passNum(5u);

    auto passBool = wren.method("main", "passBool", "call(_)");
    passBool(true);

    auto passStr = wren.method("main", "passString", "call(_)");
    passStr("hello");
    passStr(std::string("hello"));
}

void testClassMethods()
{
    wrenpp::VM vm;
    bindVectorModule(vm);
    vm.executeModule("test_vector");
}

void testProperties()
{
    wrenpp::VM vm;
    bindVectorModule(vm);
    bindTransformModule(vm);
    vm.executeModule("test_properties");
}

void testReturnValues()
{
    wrenpp::VM vm{};

    vm.executeString(
        "var returnsThree = Fn.new {\n"
        "    return 3\n"
        "}\n"
        "var returnsTrue = Fn.new {\n"
        "    return true\n"
        "}\n"
        "var returnsGreeting = Fn.new {\n"
        "    return \"Hello, world\"\n"
        "}\n");
    wrenpp::Method returnsThree = vm.method("main", "returnsThree", "call()");
    double nval = returnsThree().as<double>();
    assert(nval == 3.0);
    wrenpp::Method returnsTrue = vm.method("main", "returnsTrue", "call()");
    bool bval = returnsTrue().as<bool>();
    assert(bval == true);
    wrenpp::Method returnsGreeting = vm.method("main", "returnsGreeting", "call()");
    wrenpp::Value sval = returnsGreeting();
    assert(!strcmp("Hello, world", sval.as<const char*>()));
}

void printConstRefString(const std::string& str) { std::printf("%s\n", str.c_str()); }

void printValueString(std::string str) { std::printf("%s\n", str.c_str()); }

void printCharString(const char* str) { std::printf("%s\n", str); }

void testStrings()
{
    wrenpp::VM vm;

    vm.beginModule("main")
        .beginClass("StringPrinter")
        .bindFunction<decltype(&printConstRefString), printConstRefString>(true, "print1(_)")
        .bindFunction<decltype(&printValueString), printValueString>(true, "print2(_)")
        .bindFunction<decltype(&printCharString), printCharString>(true, "print3(_)")
        .endClass();

    vm.executeString(
        "class StringPrinter {\n"
        "  foreign static print1(str)\n"
        "  foreign static print2(str)\n"
        "  foreign static print3(str)\n"
        "}\n");

    vm.executeString("StringPrinter.print1(\"passing by const ref works\")");
    vm.executeString("StringPrinter.print2(\"passing by value works\")");
    vm.executeString("StringPrinter.print3(\"passing as C string works\")");
}

int main()
{

    std::printf("\nCalling Wren code from C++...\n\n");

    testMethodCall();

    std::printf("\nTesting method calls...\n\n");

    testClassMethods();

    std::printf("\nTesting properties...\n\n");

    testProperties();

    std::printf("\nTesting return values...\n\n");

    testReturnValues();

    std::printf("\nTesting to see if passing string to C++ works...\n\n");

    testStrings();

    return 0;
}
<commit_msg>Fix method test<commit_after>#include "Wren++.h"
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <cstring>

// a small class to test class & method binding with
struct Vec3
{
    float x, y, z;

    Vec3(float x, float y, float z) : x{x}, y{y}, z{z} {}

    Vec3(const Vec3&) = default;

    float norm() const { return std::sqrt(x * x + y * y + z * z); }

    float dot(const Vec3& rhs) const { return x * rhs.x + y * rhs.y + z * rhs.z; }

    Vec3 cross(const Vec3& rhs) const
    {
        return Vec3{y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x};
    }

    Vec3 plus(const Vec3& rhs) const { return Vec3{x + rhs.x, y + rhs.y, z + rhs.z}; }
};

struct Transform
{
    Transform(const Vec3& p) : position(p) {}

    Vec3 position{0.f, 0.f, 0.f};
};

void CFunctionVectorReference(WrenVM* vm)
{
    static Vec3 v{2.0, 1.0, 1.0};
    wrenpp::setSlotForeignPtr(vm, 0, &v);
}

Vec3* returnVec3Ptr()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return &v;
}

Vec3& returnVec3Ref()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return v;
}

const Vec3* returnVec3ConstPtr()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return &v;
}

const Vec3& returnVec3ConstRef()
{
    static Vec3 v{1.f, 1.f, 1.f};
    return v;
}

void bindVectorModule(wrenpp::VM& vm)
{
    vm.beginModule("vector")
        .bindClass<Vec3, float, float, float>("Vec3")
        .bindGetter<decltype(Vec3::x), &Vec3::x>("x")
        .bindSetter<decltype(Vec3::x), &Vec3::x>("x=(_)")
        .bindGetter<decltype(Vec3::y), &Vec3::y>("y")
        .bindSetter<decltype(Vec3::y), &Vec3::y>("y=(_)")
        .bindGetter<decltype(Vec3::z), &Vec3::z>("z")
        .bindSetter<decltype(Vec3::z), &Vec3::z>("z=(_)")
        .bindMethod<decltype(&Vec3::norm), &Vec3::norm>(false, "norm()")
        .bindMethod<decltype(&Vec3::dot), &Vec3::dot>(false, "dot(_)")
        .bindMethod<decltype(&Vec3::plus), &Vec3::plus>(false, "plus(_)")
        .endClass()
        .endModule();
    vm.beginModule("main")
        .beginClass("VectorReferences")
        .bindCFunction(true, "getCFunction()", CFunctionVectorReference)
        .bindFunction<decltype(&returnVec3Ptr), &returnVec3Ptr>(true, "getPtr()")
        .bindFunction<decltype(&returnVec3Ref), &returnVec3Ref>(true, "getRef()")
        .bindFunction<decltype(&returnVec3ConstPtr), &returnVec3ConstPtr>(true, "getConstPtr()")
        .bindFunction<decltype(&returnVec3ConstRef), returnVec3ConstRef>(true, "getConstRef()")
        .endClass()
        .endModule();
}

void bindTransformModule(wrenpp::VM& vm)
{
    vm.beginModule("transform")
        .bindClass<Transform, Vec3>("Transform")
        .bindSetter<decltype(Transform::position), &Transform::position>("position=(_)")
        .bindGetter<decltype(Transform::position), &Transform::position>("position");
}

void testMethodCall()
{
    wrenpp::VM wren{};

    wren.executeModule("test_method");
    auto passNum = wren.method("test_method", "passNumber", "call(_)");
    passNum(5.0);
    passNum(5.f);
    passNum(5);
    passNum(5u);

    auto passBool = wren.method("test_method", "passBool", "call(_)");
    passBool(true);

    auto passStr = wren.method("test_method", "passString", "call(_)");
    passStr("hello");
    passStr(std::string("hello"));
}

void testClassMethods()
{
    wrenpp::VM vm;
    bindVectorModule(vm);
    vm.executeModule("test_vector");
}

void testProperties()
{
    wrenpp::VM vm;
    bindVectorModule(vm);
    bindTransformModule(vm);
    vm.executeModule("test_properties");
}

void testReturnValues()
{
    wrenpp::VM vm{};

    vm.executeString(
        "var returnsThree = Fn.new {\n"
        "    return 3\n"
        "}\n"
        "var returnsTrue = Fn.new {\n"
        "    return true\n"
        "}\n"
        "var returnsGreeting = Fn.new {\n"
        "    return \"Hello, world\"\n"
        "}\n");
    wrenpp::Method returnsThree = vm.method("main", "returnsThree", "call()");
    double nval = returnsThree().as<double>();
    assert(nval == 3.0);
    wrenpp::Method returnsTrue = vm.method("main", "returnsTrue", "call()");
    bool bval = returnsTrue().as<bool>();
    assert(bval == true);
    wrenpp::Method returnsGreeting = vm.method("main", "returnsGreeting", "call()");
    wrenpp::Value sval = returnsGreeting();
    assert(!strcmp("Hello, world", sval.as<const char*>()));
}

void printConstRefString(const std::string& str) { std::printf("%s\n", str.c_str()); }

void printValueString(std::string str) { std::printf("%s\n", str.c_str()); }

void printCharString(const char* str) { std::printf("%s\n", str); }

void testStrings()
{
    wrenpp::VM vm;

    vm.beginModule("main")
        .beginClass("StringPrinter")
        .bindFunction<decltype(&printConstRefString), printConstRefString>(true, "print1(_)")
        .bindFunction<decltype(&printValueString), printValueString>(true, "print2(_)")
        .bindFunction<decltype(&printCharString), printCharString>(true, "print3(_)")
        .endClass();

    vm.executeString(
        "class StringPrinter {\n"
        "  foreign static print1(str)\n"
        "  foreign static print2(str)\n"
        "  foreign static print3(str)\n"
        "}\n");

    vm.executeString("StringPrinter.print1(\"passing by const ref works\")");
    vm.executeString("StringPrinter.print2(\"passing by value works\")");
    vm.executeString("StringPrinter.print3(\"passing as C string works\")");
}

int main()
{

    std::printf("\nCalling Wren code from C++...\n\n");

    testMethodCall();

    std::printf("\nTesting method calls...\n\n");

    testClassMethods();

    std::printf("\nTesting properties...\n\n");

    testProperties();

    std::printf("\nTesting return values...\n\n");

    testReturnValues();

    std::printf("\nTesting to see if passing string to C++ works...\n\n");

    testStrings();

    return 0;
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "catch.hpp"

#include "dll/conv_layer.hpp"
#include "dll/dense_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/dense_stochastic_gradient_descent.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

namespace {

template<typename Dataset>
void mnist_scale(Dataset& dataset){
    for(auto& image : dataset.training_images){
        for(auto& pixel : image){
            pixel *= (1.0 / 256.0);
        }
    }

    for(auto& image : dataset.test_images){
        for(auto& pixel : image){
            pixel *= (1.0 / 256.0);
        }
    }
}

} //end of anonymous namespace

TEST_CASE( "conv/sgd/1", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::SIGMOID>>::layer_t,
            dll::dense_desc<10 * 24 * 24, 10, dll::activation<dll::function::SIGMOID>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE( "conv/sgd/2", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::TANH>>::layer_t,
            dll::dense_desc<10 * 24 * 24, 10, dll::activation<dll::function::TANH>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE( "conv/sgd/3", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_desc<10 * 24 * 24, 10, dll::activation<dll::function::TANH>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE( "conv/sgd/4", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::SIGMOID>>::layer_t,
            dll::conv_desc<10, 24, 24, 6, 20, 20, dll::activation<dll::function::SIGMOID>>::layer_t,
            dll::dense_desc<6 * 20 * 20, 10, dll::activation<dll::function::SIGMOID>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}
<commit_msg>New test<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <deque>

#include "catch.hpp"

#include "dll/conv_layer.hpp"
#include "dll/dense_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/dense_stochastic_gradient_descent.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

namespace {

template<typename Dataset>
void mnist_scale(Dataset& dataset){
    for(auto& image : dataset.training_images){
        for(auto& pixel : image){
            pixel *= (1.0 / 256.0);
        }
    }

    for(auto& image : dataset.test_images){
        for(auto& pixel : image){
            pixel *= (1.0 / 256.0);
        }
    }
}

} //end of anonymous namespace

TEST_CASE( "conv/sgd/1", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::SIGMOID>>::layer_t,
            dll::dense_desc<10 * 24 * 24, 10, dll::activation<dll::function::SIGMOID>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE( "conv/sgd/2", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::TANH>>::layer_t,
            dll::dense_desc<10 * 24 * 24, 10, dll::activation<dll::function::TANH>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE( "conv/sgd/3", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_desc<10 * 24 * 24, 10, dll::activation<dll::function::TANH>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE( "conv/sgd/4", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::SIGMOID>>::layer_t,
            dll::conv_desc<10, 24, 24, 6, 20, 20, dll::activation<dll::function::SIGMOID>>::layer_t,
            dll::dense_desc<6 * 20 * 20, 10, dll::activation<dll::function::SIGMOID>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}

TEST_CASE( "conv/sgd/5", "[dense][dbn][mnist][sgd]" ) {
    typedef dll::dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 10, 24, 24, dll::activation<dll::function::RELU>>::layer_t,
            dll::conv_desc<10, 24, 24, 6, 20, 20, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_desc<6 * 20 * 20, 200, dll::activation<dll::function::RELU>>::layer_t,
            dll::dense_desc<200, 10, dll::activation<dll::function::SIGMOID>>::layer_t
        >
        , dll::trainer<dll::dense_sgd_trainer>
        , dll::batch_size<10>
    >::dbn_t dbn_t;

    auto dataset = mnist::read_dataset<std::vector, std::vector, double>(1000);
    REQUIRE(!dataset.training_images.empty());

    mnist_scale(dataset);

    auto dbn = std::make_unique<dbn_t>();

    dbn->learning_rate = 0.05;

    auto ft_error = dbn->fine_tune(dataset.training_images, dataset.training_labels, 100);
    std::cout << "ft_error:" << ft_error << std::endl;

    CHECK(ft_error < 5e-2);

    auto test_error = dll::test_set(dbn, dataset.test_images, dataset.test_labels, dll::predictor());
    std::cout << "test_error:" << test_error << std::endl;
    REQUIRE(test_error < 0.2);
}
<|endoftext|>


<commit_before>/*
*
*/

#include <iostream>
#include <list>
#include <chrono>
#include "shared_allocator/shared_allocator.hpp"
#include "shared_allocator/cached_allocator.hpp"
#include "shared_allocator/size_cached_allocator.hpp"

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

bool test1()
{
    const salloc::shared_allocator<int> alloc;

    int* ints = alloc.allocate(100);
    if (ints == nullptr)
    {
        return false;
    }

    if (alloc.size(ints) != 100)
    {
        return false;
    }

    for (int i = 0; i < 100; ++i)
    {
        alloc.construct(ints + i, i + 1);
    }

    for (int i = 99; i > -1; --i)
    {
        if (ints[i] != i + 1)
        {
            return false;
        }
    }

    alloc.deallocate(ints);

    return true;
}

//////////////////////////////////////////////////////////////////////////

bool test2()
{
    salloc::cached_allocator<int> alloc;

    int* ints = alloc.allocate();
    if (ints == nullptr)
    {
        return false;
    }

    if (alloc.size(ints) != 1)
    {
        return false;
    }

    alloc.construct(ints, 333);
    if (*ints != 333)
    {
        return false;
    }

    alloc.deallocate(ints);

    int* int2 = alloc.allocate();
    if (int2 == nullptr)
    {
        return false;
    }

    if (ints != int2)
    {
        return false;
    }

    int* int3 = alloc.allocate();
    if (int3 == nullptr)
    {
        return false;
    }

    if (ints == int3 || int2 == int3)
    {
        return false;
    }

    return true;
}

//////////////////////////////////////////////////////////////////////////

bool test3()
{
    static const int observations_number = 100000;
    static const int array_size = 1000;
    static const double observation_freq = 1.0 / double(observations_number);

    const salloc::shared_allocator<double> alloc1;
    std::allocator<double> alloc2;

    std::cout << std::endl;

    double shared_alloc_time = 0, shared_dealloc_time = 0;
    double std_alloc_time = 0, std_dealloc_time = 0;

    double** pointers = new double*[observations_number];
    memset(pointers, 0, observations_number * sizeof(double*));

    typedef decltype(std::chrono::high_resolution_clock::now()) Time;
    Time t1, t2;

    auto shared_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc1.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc1.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    auto std_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc2.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc2.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    int n = 0;
    for (int i = 0; i < observations_number; ++i)
    {
        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;

        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;
    }

    const double one_to_n = 1.0 / double(n);

    shared_alloc_time *= one_to_n;
    shared_dealloc_time *= one_to_n;

    std_alloc_time *= one_to_n;
    std_dealloc_time *= one_to_n;

    std::cout << "shared_allocator<double>  allocate(" << array_size << ") time = " << shared_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << shared_dealloc_time << " ns\n";

    std::cout << "std::allocator<double>  allocate(" << array_size << ") time = " << std_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << std_dealloc_time << " ns\n";

    delete[] pointers;

    return true;
}

//////////////////////////////////////////////////////////////////////////

bool test4()
{
    static const int observations_number = 100000;
    static const int array_size = 1000;
    static const double observation_freq = 1.0 / double(observations_number);

    salloc::cached_allocator<double> alloc1;
    std::allocator<double> alloc2;

    std::cout << std::endl;

    double shared_alloc_time = 0, shared_dealloc_time = 0;
    double std_alloc_time = 0, std_dealloc_time = 0;

    double** pointers = new double*[observations_number];
    memset(pointers, 0, observations_number * sizeof(double*));

    typedef decltype(std::chrono::high_resolution_clock::now()) Time;
    Time t1, t2;

    auto shared_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc1.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc1.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    auto std_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc2.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc2.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    alloc1.reserve(array_size, 1);

    int n = 0;
    for (int i = 0; i < observations_number; ++i)
    {
        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;

        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;
    }

    const double one_to_n = 1.0 / double(n);

    shared_alloc_time *= one_to_n;
    shared_dealloc_time *= one_to_n;

    std_alloc_time *= one_to_n;
    std_dealloc_time *= one_to_n;

    std::cout << "cached_allocator<double>  allocate(" << array_size << ") time = " << shared_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << shared_dealloc_time << " ns\n";

    std::cout << "std::allocator<double>  allocate(" << array_size << ") time = " << std_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << std_dealloc_time << " ns\n";

    delete[] pointers;

    return true;
}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

typedef bool(*pTest)();

const pTest tests[] = {
    test1,
    test2,
    test3,
    test4
};

//////////////////////////////////////////////////////////////////////////

int main()
{
    std::list<int> l1;
    std::list<int, salloc::shared_allocator<int> > l2;
    std::list<int, salloc::cached_allocator<int> > l3;

    std::cout << "Begin testing...\n";

    int result = 0;

    int i = 0;
    for (auto test : tests)
    {
        ++i;

        std::cout << "--- Test" << i << ": ";
        if (!test())
        {
            result = -1;
            std::cout << "FAILED!";
        }
        else
        {
            std::cout << "OK!";
        }

        std::cout << std::endl;
    }

    std::cout << "Testing complete.\n";

    char c = 0;
    std::cin >> c;

    return result;
}
<commit_msg>visual improvement for test<commit_after>/*
*
*/

#include <iostream>
#include <list>
#include <chrono>
#include "shared_allocator/shared_allocator.hpp"
#include "shared_allocator/cached_allocator.hpp"
#include "shared_allocator/size_cached_allocator.hpp"

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

bool test1()
{
    const salloc::shared_allocator<int> alloc;

    int* ints = alloc.allocate(100);
    if (ints == nullptr)
    {
        return false;
    }

    if (alloc.size(ints) != 100)
    {
        return false;
    }

    for (int i = 0; i < 100; ++i)
    {
        alloc.construct(ints + i, i + 1);
    }

    for (int i = 99; i > -1; --i)
    {
        if (ints[i] != i + 1)
        {
            return false;
        }
    }

    alloc.deallocate(ints);

    return true;
}

//////////////////////////////////////////////////////////////////////////

bool test2()
{
    salloc::cached_allocator<int> alloc;

    int* ints = alloc.allocate();
    if (ints == nullptr)
    {
        return false;
    }

    if (alloc.size(ints) != 1)
    {
        return false;
    }

    alloc.construct(ints, 333);
    if (*ints != 333)
    {
        return false;
    }

    alloc.deallocate(ints);

    int* int2 = alloc.allocate();
    if (int2 == nullptr)
    {
        return false;
    }

    if (ints != int2)
    {
        return false;
    }

    int* int3 = alloc.allocate();
    if (int3 == nullptr)
    {
        return false;
    }

    if (ints == int3 || int2 == int3)
    {
        return false;
    }

    return true;
}

//////////////////////////////////////////////////////////////////////////

bool test3()
{
    static const int observations_number = 100000;
    static const int array_size = 1000;
    static const double observation_freq = 1.0 / double(observations_number);

    const salloc::shared_allocator<double> alloc1;
    std::allocator<double> alloc2;

    std::cout << std::endl;

    double shared_alloc_time = 0, shared_dealloc_time = 0;
    double std_alloc_time = 0, std_dealloc_time = 0;

    double** pointers = new double*[observations_number];
    memset(pointers, 0, observations_number * sizeof(double*));

    typedef decltype(std::chrono::high_resolution_clock::now()) Time;
    Time t1, t2;

    auto shared_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc1.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc1.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    auto std_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc2.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc2.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    int n = 0;
    for (int i = 0; i < observations_number; ++i)
    {
        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;

        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;
    }

    const double one_to_n = 1.0 / double(n);

    shared_alloc_time *= one_to_n;
    shared_dealloc_time *= one_to_n;

    std_alloc_time *= one_to_n;
    std_dealloc_time *= one_to_n;

    std::cout << "shared_allocator<double>  allocate(" << array_size << ") time = " << shared_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << shared_dealloc_time << " ns\n";

    std::cout << "std::allocator<double>  allocate(" << array_size << ") time = " << std_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << std_dealloc_time << " ns\n";

    delete[] pointers;

    return true;
}

//////////////////////////////////////////////////////////////////////////

bool test4()
{
    static const int observations_number = 100000;
    static const int array_size = 1000;
    static const double observation_freq = 1.0 / double(observations_number);

    salloc::cached_allocator<double> alloc1;
    std::allocator<double> alloc2;

    std::cout << std::endl;

    double shared_alloc_time = 0, shared_dealloc_time = 0;
    double std_alloc_time = 0, std_dealloc_time = 0;

    double** pointers = new double*[observations_number];
    memset(pointers, 0, observations_number * sizeof(double*));

    typedef decltype(std::chrono::high_resolution_clock::now()) Time;
    Time t1, t2;

    auto shared_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc1.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc1.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        shared_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    auto std_alloc_dealloc = [&](int i)
    {
        t1 = std::chrono::high_resolution_clock::now();
        pointers[i] = alloc2.allocate(array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_alloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());

        t1 = std::chrono::high_resolution_clock::now();
        alloc2.deallocate(pointers[i], array_size);
        t2 = std::chrono::high_resolution_clock::now();

        std_dealloc_time += double(std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count());
    };

    alloc1.reserve(array_size, 1);

    int n = 0;
    for (int i = 0; i < observations_number; ++i)
    {
        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;

        shared_alloc_dealloc(i);
        std_alloc_dealloc(i);
        ++n;
    }

    const double one_to_n = 1.0 / double(n);

    shared_alloc_time *= one_to_n;
    shared_dealloc_time *= one_to_n;

    std_alloc_time *= one_to_n;
    std_dealloc_time *= one_to_n;

    std::cout << "cached_allocator<double>  allocate(" << array_size << ") time = " << shared_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << shared_dealloc_time << " ns\n";

    std::cout << "std::allocator<double>  allocate(" << array_size << ") time = " << std_alloc_time << " ns  ";
    std::cout << "deallocate(" << array_size << ") time = " << std_dealloc_time << " ns\n";

    delete[] pointers;

    return true;
}

//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

typedef bool(*pTest)();

const pTest tests[] = {
    test1,
    test2,
    test3,
    test4
};

//////////////////////////////////////////////////////////////////////////

int main()
{
    std::list<int> l1;
    std::list<int, salloc::shared_allocator<int> > l2;
    std::list<int, salloc::cached_allocator<int> > l3;

    std::cout << "Begin testing...\n";

    int result = 0;

    int i = 0;
    for (auto test : tests)
    {
        ++i;

        std::cout << "--- Test" << i << ": ";
        if (!test())
        {
            result = -1;
            std::cout << "FAILED!";
        }
        else
        {
            std::cout << "OK!";
        }

        std::cout << std::endl;
    }

    std::cout << "Testing complete.\nInput something to exit: ";

    char c = 0;
    std::cin >> c;

    return result;
}
<|endoftext|>


<commit_before>#include <vmu.hpp>
#include <memory>

#include <catch_with_main.hpp>

template<class Address, class Address2>
void check_region(const vmu::basic_region<Address> region, Address2 addr)
{
    REQUIRE(static_cast<bool>(region));
    CHECK(region.protection().readable());
    CHECK(region.protection().writable());
    CHECK(region.size() != 0);
    CHECK(vmu::detail::uintptr_cast(region.begin()) <= vmu::detail::uintptr_cast(addr));
    CHECK(vmu::detail::uintptr_cast(region.end()) >= vmu::detail::uintptr_cast(addr));
}

TEST_CASE("address_cast sanity check")
{
    std::uintptr_t uintptr = 0xdeadbeef;
    void* ptr = vmu::detail::address_cast<void*>(uintptr);
    REQUIRE(memcmp(&uintptr, &ptr, sizeof(void*)) == 0);
}

TEST_CASE("query")
{
    int  i     = 5;
    auto ret   = vmu::query(&i);
    check_region(ret, &i);
}

TEST_CASE("query error code")
{
    std::error_code ec;
    int  i     = 5;
    auto ptr_i = reinterpret_cast<std::uintptr_t>(&i);
    auto ret   = vmu::query(ptr_i, ec);
    check_region(ret, ptr_i);
}

TEST_CASE("query_range")
{
    int  i    = 5;
    auto ptr  = reinterpret_cast<std::uintptr_t>(&i);
    const auto rets = vmu::query_range(ptr, ptr + 16);

    REQUIRE_FALSE(rets.empty());
    for(const auto& ret : rets)
        check_region(ret, ptr);
}

TEST_CASE("query_range error code")
{
    int  i    = 5;
    auto ptr  = reinterpret_cast<std::uintptr_t>(&i);
    std::error_code ec;
    const auto rets = vmu::query_range(&i, &i + 16, ec);

    REQUIRE_FALSE(ec);
    REQUIRE_FALSE(rets.empty());
    for(const auto& ret : rets)
        check_region(ret, ptr);
}

TEST_CASE("protection_guard")
{
    auto random_data = std::make_unique<unsigned char[]>(4096 * 3);
    auto testing_arr = random_data.get();
    memset(testing_arr, 12, 4096 * 3);
    auto result = vmu::query(testing_arr);
    REQUIRE(result);

    {
        const auto new_prot = vmu::access::read_write_exec;
        CHECK_FALSE(new_prot == result.protection().to_flags());

        vmu::protection_guard pg(testing_arr, new_prot);

        auto new_flags = vmu::query(testing_arr);
        CHECK(new_flags);
        CHECK(new_flags.protection().to_flags() == new_prot);
    }

    auto result2 = vmu::query(testing_arr);
    REQUIRE(result2.shared() == result.shared());
    REQUIRE(result2.begin() == result.begin());
    REQUIRE(result2.protection().to_flags() == result.protection().to_flags());
    REQUIRE(result2.guarded() == result.guarded());
}

TEST_CASE("query_iterator")
{
    const auto total_size = vmu::page_size() * 5;
    auto random_data = std::make_unique<unsigned char[]>(total_size);
    auto begin = random_data.get();
    auto end = begin + total_size;

    vmu::query_iterator end_it(end);
    for (vmu::query_iterator it(begin); it != end_it; ++it) {
        REQUIRE(static_cast<bool>(*it));
        CHECK(it->protection().readable());
        CHECK(it->protection().writable());
        CHECK(it->size() != 0);
    }
}
<commit_msg>added 1 more test<commit_after>#include <vmu.hpp>
#include <memory>

#include <catch_with_main.hpp>

template<class Address, class Address2>
void check_region(const vmu::basic_region<Address> region, Address2 addr)
{
    REQUIRE(static_cast<bool>(region));
    CHECK(region.protection().readable());
    CHECK(region.protection().writable());
    CHECK(region.size() != 0);
    CHECK(vmu::detail::uintptr_cast(region.begin()) <= vmu::detail::uintptr_cast(addr));
    CHECK(vmu::detail::uintptr_cast(region.end()) >= vmu::detail::uintptr_cast(addr));
}

TEST_CASE("address_cast sanity check")
{
    std::uintptr_t uintptr = 0xdeadbeef;
    void* ptr = vmu::detail::address_cast<void*>(uintptr);
    REQUIRE(memcmp(&uintptr, &ptr, sizeof(void*)) == 0);
}

TEST_CASE("query")
{
    int  i     = 5;
    auto ret   = vmu::query(&i);
    check_region(ret, &i);
}

TEST_CASE("query error code")
{
    std::error_code ec;
    int  i     = 5;
    auto ptr_i = reinterpret_cast<std::uintptr_t>(&i);
    auto ret   = vmu::query(ptr_i, ec);
    check_region(ret, ptr_i);
}

TEST_CASE("query_range")
{
    int  i    = 5;
    auto ptr  = reinterpret_cast<std::uintptr_t>(&i);
    const auto rets = vmu::query_range(ptr, ptr + 16);

    REQUIRE_FALSE(rets.empty());
    for(const auto& ret : rets)
        check_region(ret, ptr);
}

TEST_CASE("query_range error code")
{
    int  i    = 5;
    auto ptr  = reinterpret_cast<std::uintptr_t>(&i);
    std::error_code ec;
    const auto rets = vmu::query_range(&i, &i + 16, ec);

    REQUIRE_FALSE(ec);
    REQUIRE_FALSE(rets.empty());
    for(const auto& ret : rets)
        check_region(ret, ptr);
}

TEST_CASE("protection_guard(Address, protection_t)")
{
    auto random_data = std::make_unique<unsigned char[]>(4096 * 3);
    auto testing_arr = random_data.get();
    memset(testing_arr, 12, 4096 * 3);
    auto result = vmu::query(testing_arr);
    REQUIRE(result);

    {
        const auto new_prot = vmu::access::read_write_exec;
        CHECK_FALSE(new_prot == result.protection().to_flags());

        vmu::protection_guard pg(testing_arr, new_prot);

        auto new_flags = vmu::query(testing_arr);
        CHECK(new_flags);
        CHECK(new_flags.protection().to_flags() == new_prot);
    }

    auto result2 = vmu::query(testing_arr);
    REQUIRE(result2.shared() == result.shared());
    REQUIRE(result2.begin() == result.begin());
    REQUIRE(result2.protection().to_flags() == result.protection().to_flags());
    REQUIRE(result2.guarded() == result.guarded());
}

TEST_CASE("protection_guard(Address, Address, protection_t)")
{
    auto random_data = std::make_unique<unsigned char[]>(4096 * 3);
    auto testing_arr = random_data.get();
    memset(testing_arr, 12, 4096 * 3);
    auto result = vmu::query(testing_arr);
    REQUIRE(result);

    {
        const auto new_prot = vmu::access::read;
        CHECK_FALSE(new_prot == result.protection().to_flags());

        vmu::protection_guard pg(testing_arr, testing_arr + 4096 * 3, new_prot);

        auto new_flags = vmu::query(testing_arr);
        CHECK(new_flags);
        CHECK(new_flags.protection().to_flags() == new_prot);
    }

    auto result2 = vmu::query(testing_arr);
    REQUIRE(result2.shared()                == result.shared());
    REQUIRE(result2.begin()                 == result.begin());
    REQUIRE(result2.protection().to_flags() == result.protection().to_flags());
    REQUIRE(result2.guarded()               == result.guarded());
}

TEST_CASE("query_iterator")
{
    const auto total_size = vmu::page_size() * 5;
    auto random_data = std::make_unique<unsigned char[]>(total_size);
    auto begin = random_data.get();
    auto end = begin + total_size;

    vmu::query_iterator end_it(end);
    for (vmu::query_iterator it(begin); it != end_it; ++it) {
        REQUIRE(static_cast<bool>(*it));
        CHECK(it->protection().readable());
        CHECK(it->protection().writable());
        CHECK(it->size() != 0);
    }
}
<|endoftext|>


<commit_before>/***************************************************************************
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay                     *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#include <Python.h>

#include "pybind11/numpy.h"
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "numpy/arrayobject.h"

#include "gtest/gtest.h"
#include <iostream>

int main(int argc, char* argv[])
{
    // Initialize all the things (google-test and Python interpreter)
    Py_Initialize();
    ::testing::InitGoogleTest(&argc, argv);

    // Run test suite
    int ret = RUN_ALL_TESTS();

    // Closure of the Python interpreter
    Py_Finalize();
    return ret;
}

<commit_msg>Includes<commit_after>/***************************************************************************
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay                     *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#include <Python.h>

#include "gtest/gtest.h"

int main(int argc, char* argv[])
{
    // Initialize all the things (google-test and Python interpreter)
    Py_Initialize();
    ::testing::InitGoogleTest(&argc, argv);

    // Run test suite
    int ret = RUN_ALL_TESTS();

    // Closure of the Python interpreter
    Py_Finalize();
    return ret;
}

<|endoftext|>


<commit_before>/*
 * waterspout
 *
 *   - simd abstraction library for audio/image manipulation -
 *
 * Copyright (c) 2013 Lucio Asnaghi
 *
 *
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <waterspout.h>

#include <ctime>
#include <stdexcept>
#include <iostream>
#include <iomanip>

using namespace waterspout;

//==============================================================================

//------------------------------------------------------------------------------

/**
 * The timer class to measure elapsed time and benchmarking
 */

class timer
{
public:
    timer()
    {
        restart();
    }

    virtual ~timer()
    {
    }

    void restart()
    {
        stopped_ = false;
        clock_start_ = time_now();
        cpu_start_ = clock();
    }

    virtual void stop()
    {
        stopped_ = true;
        cpu_end_ = clock();
        clock_end_ = time_now();
    }

    double cpu_elapsed()
    {
        // return elapsed CPU time in ms
        if (! stopped_)
        {
            stop();
        }

        return ((double)(cpu_end_ - cpu_start_)) / CLOCKS_PER_SEC * 1000.0;
    }

    double clock_elapsed()
    {
        // return elapsed wall clock time in ms
        if (! stopped_)
        {
            stop();
        }

        return (clock_end_ - clock_start_) * 1000.0;
    }

    forcedinline double time_now()
    {
#if defined(WATERSPOUT_COMPILER_MSVC)
        LARGE_INTEGER t, f;
        QueryPerformanceCounter(&t);
        QueryPerformanceFrequency(&f);
        return double(t.QuadPart) / double(f.QuadPart);
#else
        struct timeval t;
        struct timezone tzp;
        gettimeofday(&t, &tzp);
        return t.tv_sec + t.tv_usec * 1e-6;
#endif
    }

protected:
    double clock_start_, clock_end_;
    clock_t cpu_start_, cpu_end_;
    bool stopped_;
};

//------------------------------------------------------------------------------

namespace {

//------------------------------------------------------------------------------

template<typename T>
void check_buffer_is_value(T* buffer, uint32 size, T value)
{
    for (uint32 i = 0; i < size; ++i)
    {
        if (buffer[i] != value)
        {
            std::clog << "Errors at index "
                      << i << " (" << buffer[i] << "!=" << value << ")" << std::endl;

            throw std::runtime_error("Buffer is not a specific value !");
        }
    }
}

template<typename T>
void check_buffer_is_zero(T* buffer, uint32 size)
{
    check_buffer_is_value(buffer, size, static_cast<T>(0));
}

template<typename T>
void check_buffers_are_equal(T* a, T* b, uint32 size)
{
    for (uint32 i = 0; i < size; ++i)
    {
        if (a[i] != b[i])
        {
            std::clog << "Errors at index "
                      << i << " (" << a[i] << "!=" << b[i] << ")" << std::endl;

            throw std::runtime_error("Buffers are not equal !");
        }
    }
}

//------------------------------------------------------------------------------

#define run_typed_test_by_flag(datatype) \
    { \
    datatype## _buffer src_buffer_a1(s); \
    datatype## _buffer src_buffer_a2(s); \
    datatype## _buffer src_buffer_b1(s); \
    datatype## _buffer src_buffer_b2(s); \
    datatype## _buffer dst_buffer_1(s); \
    datatype## _buffer dst_buffer_2(s); \
    \
    std::clog << " - clear_buffer_" << #datatype << std::endl; \
    simd->clear_buffer_ ##datatype (src_buffer_a1.data(), s); \
    fpu->clear_buffer_ ##datatype (src_buffer_a2.data(), s); \
    check_buffers_are_equal(src_buffer_a1.data(), src_buffer_a2.data(), s); \
    \
    std::clog << " - set_buffer_" << #datatype << std::endl; \
    simd->set_buffer_ ##datatype (src_buffer_a1.data(), s, (datatype)1); \
    fpu->set_buffer_ ##datatype (src_buffer_a2.data(), s, (datatype)1); \
    simd->set_buffer_ ##datatype (src_buffer_b1.data(), s, (datatype)500); \
    fpu->set_buffer_ ##datatype (src_buffer_b2.data(), s, (datatype)500); \
    check_buffers_are_equal(src_buffer_a1.data(), src_buffer_a2.data(), s); \
    check_buffers_are_equal(src_buffer_b1.data(), src_buffer_b2.data(), s); \
    \
    std::clog << " - scale_buffer_" << #datatype << std::endl; \
    simd->scale_buffer_ ##datatype (src_buffer_a1.data(), s, 2.0f); \
    fpu->scale_buffer_ ##datatype (src_buffer_a2.data(), s, 2.0f); \
    check_buffers_are_equal(src_buffer_a1.data(), src_buffer_a2.data(), s); \
    \
    std::clog << " - copy_buffer_" << #datatype << std::endl; \
    simd->copy_buffer_ ##datatype (src_buffer_a1.data(), dst_buffer_1.data(), s); \
    fpu->copy_buffer_ ##datatype (src_buffer_a2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - add_buffers_" << #datatype << std::endl; \
    simd->add_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->add_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - subtract_buffers_" << #datatype << std::endl; \
    simd->subtract_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->subtract_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - multiply_buffers_" << #datatype << std::endl; \
    simd->multiply_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->multiply_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - divide_buffers_" << #datatype << std::endl; \
    simd->set_buffer_ ##datatype (src_buffer_b1.data(), s, (datatype)2); \
    fpu->set_buffer_ ##datatype (src_buffer_b2.data(), s, (datatype)2); \
    simd->divide_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->divide_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << std::endl; \
    }

#define run_all_tests_by_flag(flags) \
    { \
    const uint32 s = 8192; \
    math fpu(FORCE_FPU); \
    math simd(flags); \
    std::clog << simd.name() << ": " << std::endl; \
    run_typed_test_by_flag(int8); \
    run_typed_test_by_flag(uint8); \
    run_typed_test_by_flag(int16); \
    run_typed_test_by_flag(uint16); \
    run_typed_test_by_flag(int32); \
    run_typed_test_by_flag(uint32); \
    run_typed_test_by_flag(int64); \
    run_typed_test_by_flag(uint64); \
    run_typed_test_by_flag(float); \
    run_typed_test_by_flag(double); \
    }

#define run_all_tests \
    run_all_tests_by_flag(FORCE_MMX); \
    run_all_tests_by_flag(FORCE_SSE); \
    run_all_tests_by_flag(FORCE_SSE2); \

    //run_all_tests_by_flag(FORCE_SSE3)
    //run_all_tests_by_flag(FORCE_SSSE3)
    //run_all_tests_by_flag(FORCE_SSE41)
    //run_all_tests_by_flag(FORCE_SSE42)
    //run_all_tests_by_flag(FORCE_AVX)

} // end namespace

//------------------------------------------------------------------------------

int main(int argc, char* argv[])
{
    run_all_tests

    return 0;
}
<commit_msg>- fix travis build<commit_after>/*
 * waterspout
 *
 *   - simd abstraction library for audio/image manipulation -
 *
 * Copyright (c) 2013 Lucio Asnaghi
 *
 *
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <waterspout.h>

#include <ctime>
#include <stdexcept>
#include <iostream>
#include <iomanip>

using namespace waterspout;

//==============================================================================

//------------------------------------------------------------------------------

/**
 * The timer class to measure elapsed time and benchmarking
 */

class timer
{
public:
    timer()
    {
        restart();
    }

    virtual ~timer()
    {
    }

    void restart()
    {
        stopped_ = false;
        clock_start_ = time_now();
        cpu_start_ = clock();
    }

    virtual void stop()
    {
        stopped_ = true;
        cpu_end_ = clock();
        clock_end_ = time_now();
    }

    double cpu_elapsed()
    {
        // return elapsed CPU time in ms
        if (! stopped_)
        {
            stop();
        }

        return ((double)(cpu_end_ - cpu_start_)) / CLOCKS_PER_SEC * 1000.0;
    }

    double clock_elapsed()
    {
        // return elapsed wall clock time in ms
        if (! stopped_)
        {
            stop();
        }

        return (clock_end_ - clock_start_) * 1000.0;
    }

    forcedinline double time_now()
    {
#if defined(WATERSPOUT_COMPILER_MSVC)
        LARGE_INTEGER t, f;
        QueryPerformanceCounter(&t);
        QueryPerformanceFrequency(&f);
        return double(t.QuadPart) / double(f.QuadPart);
#else
        struct timeval t;
        struct timezone tzp;
        gettimeofday(&t, &tzp);
        return t.tv_sec + t.tv_usec * 1e-6;
#endif
    }

protected:
    double clock_start_, clock_end_;
    clock_t cpu_start_, cpu_end_;
    bool stopped_;
};

//------------------------------------------------------------------------------

namespace {

//------------------------------------------------------------------------------

template<typename T>
void check_buffer_is_value(T* buffer, uint32 size, T value)
{
    for (uint32 i = 0; i < size; ++i)
    {
        if (buffer[i] != value)
        {
            std::clog << "Errors at index "
                      << i << " (" << buffer[i] << "!=" << value << ")" << std::endl;

            throw std::runtime_error("Buffer is not a specific value !");
        }
    }
}

template<typename T>
void check_buffer_is_zero(T* buffer, uint32 size)
{
    check_buffer_is_value(buffer, size, static_cast<T>(0));
}

template<typename T>
void check_buffers_are_equal(T* a, T* b, uint32 size)
{
    for (uint32 i = 0; i < size; ++i)
    {
        if (a[i] != b[i])
        {
            std::clog << "Errors at index "
                      << i << " (" << a[i] << "!=" << b[i] << ")" << std::endl;

            throw std::runtime_error("Buffers are not equal !");
        }
    }
}

//------------------------------------------------------------------------------

#define run_typed_test_by_flag(datatype) \
    { \
    datatype## _buffer src_buffer_a1(s); \
    datatype## _buffer src_buffer_a2(s); \
    datatype## _buffer src_buffer_b1(s); \
    datatype## _buffer src_buffer_b2(s); \
    datatype## _buffer dst_buffer_1(s); \
    datatype## _buffer dst_buffer_2(s); \
    \
    std::clog << " - clear_buffer_" << #datatype << std::endl; \
    simd->clear_buffer_ ##datatype (src_buffer_a1.data(), s); \
    fpu->clear_buffer_ ##datatype (src_buffer_a2.data(), s); \
    check_buffers_are_equal(src_buffer_a1.data(), src_buffer_a2.data(), s); \
    \
    std::clog << " - set_buffer_" << #datatype << std::endl; \
    simd->set_buffer_ ##datatype (src_buffer_a1.data(), s, (datatype)1); \
    fpu->set_buffer_ ##datatype (src_buffer_a2.data(), s, (datatype)1); \
    simd->set_buffer_ ##datatype (src_buffer_b1.data(), s, (datatype)500); \
    fpu->set_buffer_ ##datatype (src_buffer_b2.data(), s, (datatype)500); \
    check_buffers_are_equal(src_buffer_a1.data(), src_buffer_a2.data(), s); \
    check_buffers_are_equal(src_buffer_b1.data(), src_buffer_b2.data(), s); \
    \
    std::clog << " - scale_buffer_" << #datatype << std::endl; \
    simd->scale_buffer_ ##datatype (src_buffer_a1.data(), s, 2.0f); \
    fpu->scale_buffer_ ##datatype (src_buffer_a2.data(), s, 2.0f); \
    check_buffers_are_equal(src_buffer_a1.data(), src_buffer_a2.data(), s); \
    \
    std::clog << " - copy_buffer_" << #datatype << std::endl; \
    simd->copy_buffer_ ##datatype (src_buffer_a1.data(), dst_buffer_1.data(), s); \
    fpu->copy_buffer_ ##datatype (src_buffer_a2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - add_buffers_" << #datatype << std::endl; \
    simd->add_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->add_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - subtract_buffers_" << #datatype << std::endl; \
    simd->subtract_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->subtract_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - multiply_buffers_" << #datatype << std::endl; \
    simd->multiply_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->multiply_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << " - divide_buffers_" << #datatype << std::endl; \
    simd->set_buffer_ ##datatype (src_buffer_b1.data(), s, (datatype)2); \
    fpu->set_buffer_ ##datatype (src_buffer_b2.data(), s, (datatype)2); \
    simd->divide_buffers_ ##datatype (src_buffer_a1.data(), src_buffer_b1.data(), dst_buffer_1.data(), s); \
    fpu->divide_buffers_ ##datatype (src_buffer_a2.data(), src_buffer_b2.data(), dst_buffer_2.data(), s); \
    check_buffers_are_equal(dst_buffer_1.data(), dst_buffer_2.data(), s); \
    \
    std::clog << std::endl; \
    }

#define run_all_tests_by_flag(flags) \
    { \
    const uint32 s = 8192; \
    math fpu(FORCE_FPU); \
    math simd(flags); \
    std::clog << simd.name() << ": " << std::endl; \
    run_typed_test_by_flag(int8); \
    run_typed_test_by_flag(uint8); \
    run_typed_test_by_flag(int16); \
    run_typed_test_by_flag(uint16); \
    run_typed_test_by_flag(int32); \
    run_typed_test_by_flag(uint32); \
    run_typed_test_by_flag(int64); \
    run_typed_test_by_flag(uint64); \
    run_typed_test_by_flag(float); \
    run_typed_test_by_flag(double); \
    }

#define run_all_tests \
    run_all_tests_by_flag(FORCE_MMX); \
    run_all_tests_by_flag(FORCE_SSE); \
    run_all_tests_by_flag(FORCE_SSE2); \

    //run_all_tests_by_flag(FORCE_SSE3)
    //run_all_tests_by_flag(FORCE_SSSE3)
    //run_all_tests_by_flag(FORCE_SSE41)
    //run_all_tests_by_flag(FORCE_SSE42)
    //run_all_tests_by_flag(FORCE_AVX)

} // end namespace

//------------------------------------------------------------------------------

int main(int argc, char* argv[])
{
    unused(argc);
    unused(argv);

    run_all_tests

    return 0;
}
<|endoftext|>


<commit_before>/************************************************************************
* QuickProf                                                             *
* Copyright (C) 2006                                                    *
* Tyler Streeter  tylerstreeter@gmail.com                               *
* All rights reserved.                                                  *
* Web: http://quickprof.sourceforge.net                                 *
*                                                                       *
* This library is free software; you can redistribute it and/or         *
* modify it under the terms of EITHER:                                  *
*   (1) The GNU Lesser General Public License as published by the Free  *
*       Software Foundation; either version 2.1 of the License, or (at  *
*       your option) any later version. The text of the GNU Lesser      *
*       General Public License is included with this library in the     *
*       file license-LGPL.txt.                                          *
*   (2) The BSD-style license that is included with this library in     *
*       the file license-BSD.txt.                                       *
*                                                                       *
* This library is distributed in the hope that it will be useful,       *
* but WITHOUT ANY WARRANTY; without even the implied warranty of        *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
* license-LGPL.txt and license-BSD.txt for more details.                *
************************************************************************/

#include "../quickprof.h"

int randomIntUniform(int min, int max)
{
	return int((max - min + 1) * rand() / (RAND_MAX + 1.0)) + min;
}

void approxDelay(int milliseconds)
{
	int spread = (int)(0.15 * (double)milliseconds);
	int delay = milliseconds + randomIntUniform(-spread, spread);
#ifdef WIN32
	::Sleep(delay);
#else
	usleep(1000 * delay);
#endif
}

int main(int argc, char* argv[])
{
	// Seed the random number generator for the 'randomIntUniform' function.
	srand((unsigned int)time(NULL));

	// To disable profiling, simply comment out the following line.
	Profiler::init("results.dat", Profiler::BLOCK_CYCLE_SECONDS);

	hidden::Clock c;

	for (int i = 0; i < 10; ++i)
	{
		unsigned long int start = c.getTimeMicroseconds();
		approxDelay(100);
		unsigned long int stop = c.getTimeMicroseconds();

		std::cout << "clock: " << (stop - start) << std::endl;
	}

	for (int i = 0; i < 10; ++i)
	{
		unsigned long int start = c.getTimeMicroseconds();
		usleep(100000);
		unsigned long int stop = c.getTimeMicroseconds();

		std::cout << "clock: " << (stop - start) << std::endl;
	}

	for (int i = 0; i < 31; ++i)
	{
		Profiler::beginBlock("block1");
		approxDelay(100);
		Profiler::endBlock("block1");

		Profiler::beginBlock("block2");
		approxDelay(200);
		Profiler::endBlock("block2");

		Profiler::beginBlock("block3");
		approxDelay(300);
		Profiler::endBlock("block3");

		// Non-profiled code.
		approxDelay(400);

		Profiler::endProfilingCycle();
	}

	// Print the overall averages.
	std::cout << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT)
		<< std::endl;

	Profiler::destroy();

	return 0;
}
<commit_msg><commit_after>/************************************************************************
* QuickProf                                                             *
* Copyright (C) 2006                                                    *
* Tyler Streeter  tylerstreeter@gmail.com                               *
* All rights reserved.                                                  *
* Web: http://quickprof.sourceforge.net                                 *
*                                                                       *
* This library is free software; you can redistribute it and/or         *
* modify it under the terms of EITHER:                                  *
*   (1) The GNU Lesser General Public License as published by the Free  *
*       Software Foundation; either version 2.1 of the License, or (at  *
*       your option) any later version. The text of the GNU Lesser      *
*       General Public License is included with this library in the     *
*       file license-LGPL.txt.                                          *
*   (2) The BSD-style license that is included with this library in     *
*       the file license-BSD.txt.                                       *
*                                                                       *
* This library is distributed in the hope that it will be useful,       *
* but WITHOUT ANY WARRANTY; without even the implied warranty of        *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
* license-LGPL.txt and license-BSD.txt for more details.                *
************************************************************************/

#include "../quickprof.h"

int randomIntUniform(int min, int max)
{
	return int((max - min + 1) * rand() / (RAND_MAX + 1.0)) + min;
}

void approxDelay(int milliseconds)
{
	int spread = (int)(0.15 * (double)milliseconds);
	int delay = milliseconds + randomIntUniform(-spread, spread);
	std::cout << "spread: " << spread << ", delay: " << delay << std::endl;
#ifdef WIN32
	::Sleep(delay);
#else
	usleep(1000 * delay);
#endif
}

int main(int argc, char* argv[])
{
	// Seed the random number generator for the 'randomIntUniform' function.
	srand((unsigned int)time(NULL));

	// To disable profiling, simply comment out the following line.
	Profiler::init("results.dat", Profiler::BLOCK_CYCLE_SECONDS);

	hidden::Clock c;

	for (int i = 0; i < 10; ++i)
	{
		unsigned long int start = c.getTimeMicroseconds();
		approxDelay(100);
		unsigned long int stop = c.getTimeMicroseconds();

		std::cout << "clock: " << (stop - start) << std::endl;
	}

	for (int i = 0; i < 10; ++i)
	{
		unsigned long int start = c.getTimeMicroseconds();
		usleep(100000);
		unsigned long int stop = c.getTimeMicroseconds();

		std::cout << "clock: " << (stop - start) << std::endl;
	}

	for (int i = 0; i < 31; ++i)
	{
		Profiler::beginBlock("block1");
		approxDelay(100);
		Profiler::endBlock("block1");

		Profiler::beginBlock("block2");
		approxDelay(200);
		Profiler::endBlock("block2");

		Profiler::beginBlock("block3");
		approxDelay(300);
		Profiler::endBlock("block3");

		// Non-profiled code.
		approxDelay(400);

		Profiler::endProfilingCycle();
	}

	// Print the overall averages.
	std::cout << Profiler::createStatsString(Profiler::BLOCK_TOTAL_PERCENT)
		<< std::endl;

	Profiler::destroy();

	return 0;
}
<|endoftext|>


<commit_before>/*!
@file
@copyright The code is licensed under the MIT License
           <http://opensource.org/licenses/MIT>,
           Copyright (c) 2015 Niels Lohmann.
@author Niels Lohmann <http://nlohmann.me>
@see https://github.com/nlohmann/fifo_map
*/

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

#define private public
#include "fifo_map.hpp"

using nlohmann::fifo_map;

#include <string>

/// helper function to check order of keys
std::string collect_keys(const fifo_map<std::string, int>& m)
{
    std::string result;
    for (auto x : m)
    {
        result += x.first;
    }
    return result;
}

TEST_CASE("element access")
{
    fifo_map<std::string, int> m = {{"C", 1}, {"A", 2}, {"B", 3}};
    const fifo_map<std::string, int> mc = m;

    SECTION("at")
    {
        CHECK(m.at("C") == 1);
        CHECK(m.at("A") == 2);
        CHECK(m.at("B") == 3);

        CHECK_THROWS_AS(m.at("Z"), std::out_of_range);

        CHECK(mc.at("C") == 1);
        CHECK(mc.at("A") == 2);
        CHECK(mc.at("B") == 3);

        CHECK_THROWS_AS(mc.at("Z"), std::out_of_range);
    }

    SECTION("operator[]")
    {
        CHECK(m["C"] == 1);
        CHECK(m["A"] == 2);
        CHECK(m["B"] == 3);

        CHECK_NOTHROW(m["Z"]);
        CHECK(m["Z"] == 0);
    }
}

TEST_CASE("iterators")
{
    fifo_map<std::string, int> m = {{"C", 1}, {"A", 2}, {"B", 3}};
    const fifo_map<std::string, int> mc = m;

    SECTION("begin/end with nonconst object")
    {
        fifo_map<std::string, int>::iterator it = m.begin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == m.end());
    }

    SECTION("begin/end with const object")
    {
        fifo_map<std::string, int>::const_iterator it = mc.begin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == mc.end());
    }

    SECTION("cbegin/cend with nonconst object")
    {
        fifo_map<std::string, int>::const_iterator it = m.cbegin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == m.cend());
    }

    SECTION("cbegin/cend with const object")
    {
        fifo_map<std::string, int>::const_iterator it = mc.cbegin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == mc.cend());
    }

    SECTION("begin/end with nonconst object")
    {
        fifo_map<std::string, int>::iterator it = m.begin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == m.end());
    }

    SECTION("rbegin/rend with nonconst object")
    {
        fifo_map<std::string, int>::reverse_iterator it = m.rbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == m.rend());
    }

    SECTION("rbegin/rend with const object")
    {
        fifo_map<std::string, int>::const_reverse_iterator it = mc.rbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == mc.rend());
    }

    SECTION("crbegin/crend with nonconst object")
    {
        fifo_map<std::string, int>::const_reverse_iterator it = m.crbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == m.crend());
    }

    SECTION("crbegin/crend with const object")
    {
        fifo_map<std::string, int>::const_reverse_iterator it = mc.crbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == mc.crend());
    }
}

TEST_CASE("capacity")
{
    nlohmann::fifo_map<std::string, int> m_empty;
    nlohmann::fifo_map<std::string, int> m_filled = {{"A", 1}, {"B", 2}};

    SECTION("empty")
    {
        CHECK(m_empty.empty());
        CHECK(! m_filled.empty());
    }

    SECTION("size")
    {
        CHECK(m_empty.size() == 0);
        CHECK(m_filled.size() == 2);
    }

    SECTION("max_size")
    {
        CHECK(m_empty.max_size() >= m_empty.size());
        CHECK(m_filled.max_size() >= m_filled.size());
    }
}

TEST_CASE("modifiers")
{
    nlohmann::fifo_map<std::string, int> m_empty;
    nlohmann::fifo_map<std::string, int> m_filled = {{"X", 1}, {"C", 2}};

    SECTION("clear")
    {
        CHECK(!m_filled.empty());
        CHECK(m_empty.empty());
        m_filled.clear();
        m_empty.clear();
        CHECK(m_filled.empty());
        CHECK(m_empty.empty());
    }

    SECTION("insert")
    {
        SECTION("insert value_type")
        {
            // check initial state
            CHECK(m_filled.size() == 2);
            CHECK(m_filled.m_keys.size() == 2);
            CHECK(collect_keys(m_filled) == "XC");

            // insert new value
            auto res1 = m_filled.insert({"A", 3});
            CHECK(m_filled["A"] == 3);
            CHECK(res1.second == true);
            CHECK(res1.first->first == "A");
            CHECK(res1.first->second == 3);

            // check that key and value way inserted
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");

            // insert already present value
            auto res2 = m_filled.insert({"A", 3});
            CHECK(m_filled["A"] == 3);
            CHECK(res2.second == false);
            CHECK(res2.first->first == "A");
            CHECK(res2.first->second == 3);

            // check that map remained unchanged
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");
        }
    }
}
<commit_msg>more test cases<commit_after>/*!
@file
@copyright The code is licensed under the MIT License
           <http://opensource.org/licenses/MIT>,
           Copyright (c) 2015 Niels Lohmann.
@author Niels Lohmann <http://nlohmann.me>
@see https://github.com/nlohmann/fifo_map
*/

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

#define private public
#include "fifo_map.hpp"

using nlohmann::fifo_map;

#include <string>

/// helper function to check order of keys
std::string collect_keys(const fifo_map<std::string, int>& m)
{
    std::string result;
    for (auto x : m)
    {
        result += x.first;
    }
    return result;
}

TEST_CASE("element access")
{
    fifo_map<std::string, int> m = {{"C", 1}, {"A", 2}, {"B", 3}};
    const fifo_map<std::string, int> mc = m;

    SECTION("at")
    {
        CHECK(m.at("C") == 1);
        CHECK(m.at("A") == 2);
        CHECK(m.at("B") == 3);

        CHECK_THROWS_AS(m.at("Z"), std::out_of_range);

        CHECK(mc.at("C") == 1);
        CHECK(mc.at("A") == 2);
        CHECK(mc.at("B") == 3);

        CHECK_THROWS_AS(mc.at("Z"), std::out_of_range);
    }

    SECTION("operator[]")
    {
        CHECK(m["C"] == 1);
        CHECK(m["A"] == 2);
        CHECK(m["B"] == 3);

        CHECK_NOTHROW(m["Z"]);
        CHECK(m["Z"] == 0);
    }
}

TEST_CASE("iterators")
{
    fifo_map<std::string, int> m = {{"C", 1}, {"A", 2}, {"B", 3}};
    const fifo_map<std::string, int> mc = m;

    SECTION("begin/end with nonconst object")
    {
        fifo_map<std::string, int>::iterator it = m.begin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == m.end());
    }

    SECTION("begin/end with const object")
    {
        fifo_map<std::string, int>::const_iterator it = mc.begin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == mc.end());
    }

    SECTION("cbegin/cend with nonconst object")
    {
        fifo_map<std::string, int>::const_iterator it = m.cbegin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == m.cend());
    }

    SECTION("cbegin/cend with const object")
    {
        fifo_map<std::string, int>::const_iterator it = mc.cbegin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == mc.cend());
    }

    SECTION("begin/end with nonconst object")
    {
        fifo_map<std::string, int>::iterator it = m.begin();
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it == m.end());
    }

    SECTION("rbegin/rend with nonconst object")
    {
        fifo_map<std::string, int>::reverse_iterator it = m.rbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == m.rend());
    }

    SECTION("rbegin/rend with const object")
    {
        fifo_map<std::string, int>::const_reverse_iterator it = mc.rbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == mc.rend());
    }

    SECTION("crbegin/crend with nonconst object")
    {
        fifo_map<std::string, int>::const_reverse_iterator it = m.crbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == m.crend());
    }

    SECTION("crbegin/crend with const object")
    {
        fifo_map<std::string, int>::const_reverse_iterator it = mc.crbegin();
        CHECK(it->first == "B");
        CHECK(it->second == 3);
        ++it;
        CHECK(it->first == "A");
        CHECK(it->second == 2);
        ++it;
        CHECK(it->first == "C");
        CHECK(it->second == 1);
        ++it;
        CHECK(it == mc.crend());
    }
}

TEST_CASE("capacity")
{
    nlohmann::fifo_map<std::string, int> m_empty;
    nlohmann::fifo_map<std::string, int> m_filled = {{"A", 1}, {"B", 2}};

    SECTION("empty")
    {
        CHECK(m_empty.empty());
        CHECK(! m_filled.empty());
    }

    SECTION("size")
    {
        CHECK(m_empty.size() == 0);
        CHECK(m_filled.size() == 2);
    }

    SECTION("max_size")
    {
        CHECK(m_empty.max_size() >= m_empty.size());
        CHECK(m_filled.max_size() >= m_filled.size());
    }
}

TEST_CASE("modifiers")
{
    nlohmann::fifo_map<std::string, int> m_empty;
    nlohmann::fifo_map<std::string, int> m_filled = {{"X", 1}, {"C", 2}};

    SECTION("clear")
    {
        CHECK(!m_filled.empty());
        CHECK(m_empty.empty());
        m_filled.clear();
        m_empty.clear();
        CHECK(m_filled.empty());
        CHECK(m_empty.empty());
    }

    SECTION("insert")
    {
        SECTION("insert value_type (lvalue)")
        {
            // check initial state
            CHECK(m_filled.size() == 2);
            CHECK(m_filled.m_keys.size() == 2);
            CHECK(collect_keys(m_filled) == "XC");

            // insert new value
            const nlohmann::fifo_map<std::string, int>::value_type v1 = {"A", 3};
            auto res1 = m_filled.insert(v1);
            CHECK(m_filled["A"] == 3);
            CHECK(res1.second == true);
            CHECK(res1.first->first == "A");
            CHECK(res1.first->second == 3);

            // check that key and value were inserted
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");

            // insert already present value
            const nlohmann::fifo_map<std::string, int>::value_type v2 = {"A", 4};
            auto res2 = m_filled.insert(v2);
            CHECK(m_filled["A"] == 3);
            CHECK(res2.second == false);
            CHECK(res2.first->first == "A");
            CHECK(res2.first->second == 3);

            // check that map remained unchanged
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");
        }

        SECTION("insert value_type (rvalue)")
        {
            // check initial state
            CHECK(m_filled.size() == 2);
            CHECK(m_filled.m_keys.size() == 2);
            CHECK(collect_keys(m_filled) == "XC");

            // insert new value
            auto res1 = m_filled.insert({"A", 3});
            CHECK(m_filled["A"] == 3);
            CHECK(res1.second == true);
            CHECK(res1.first->first == "A");
            CHECK(res1.first->second == 3);

            // check that key and value were inserted
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");

            // insert already present value
            auto res2 = m_filled.insert({"A", 4});
            CHECK(m_filled["A"] == 3);
            CHECK(res2.second == false);
            CHECK(res2.first->first == "A");
            CHECK(res2.first->second == 3);

            // check that map remained unchanged
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");
        }

        SECTION("insert value_type (lvalue) with hint")
        {
            // check initial state
            CHECK(m_filled.size() == 2);
            CHECK(m_filled.m_keys.size() == 2);
            CHECK(collect_keys(m_filled) == "XC");

            // insert new value
            const nlohmann::fifo_map<std::string, int>::value_type v1 = {"A", 3};
            auto res1 = m_filled.insert(m_filled.end(), v1);
            CHECK(m_filled["A"] == 3);
            CHECK(res1->first == "A");
            CHECK(res1->second == 3);

            // check that key and value were inserted
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");

            // insert already present value
            const nlohmann::fifo_map<std::string, int>::value_type v2 = {"A", 4};
            auto res2 = m_filled.insert(m_filled.end(), v2);
            CHECK(m_filled["A"] == 3);
            CHECK(res2->first == "A");
            CHECK(res2->second == 3);

            // check that map remained unchanged
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");
        }

        SECTION("insert value_type (rvalue) with hint")
        {
            // check initial state
            CHECK(m_filled.size() == 2);
            CHECK(m_filled.m_keys.size() == 2);
            CHECK(collect_keys(m_filled) == "XC");

            // insert new value
            auto res1 = m_filled.insert(m_filled.end(), {"A", 3});
            CHECK(m_filled["A"] == 3);
            CHECK(res1->first == "A");
            CHECK(res1->second == 3);

            // check that key and value were inserted
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");

            // insert already present value
            auto res2 = m_filled.insert(m_filled.end(), {"A", 4});
            CHECK(m_filled["A"] == 3);
            CHECK(res2->first == "A");
            CHECK(res2->second == 3);

            // check that map remained unchanged
            CHECK(m_filled.size() == 3);
            CHECK(m_filled.m_keys.size() == 3);
            CHECK(collect_keys(m_filled) == "XCA");
        }

        SECTION("insert initializer list")
        {
            // check initial state
            CHECK(m_filled.size() == 2);
            CHECK(m_filled.m_keys.size() == 2);
            CHECK(collect_keys(m_filled) == "XC");

            // insert initializer list
            m_filled.insert({{"A", 3}, {"Z", 4}, {"B", 5}});
            CHECK(m_filled["A"] == 3);
            CHECK(m_filled["Z"] == 4);
            CHECK(m_filled["B"] == 5);

            // check that keys and values were inserted
            CHECK(m_filled.size() == 5);
            CHECK(m_filled.m_keys.size() == 5);
            CHECK(collect_keys(m_filled) == "XCAZB");

            // insert empty initializer list
            m_filled.insert({});

            // check that map remained unchanged
            CHECK(m_filled.size() == 5);
            CHECK(m_filled.m_keys.size() == 5);
            CHECK(collect_keys(m_filled) == "XCAZB");
        }
    }
}
<|endoftext|>