Skip to content

Commit

Permalink
autodiff gaussian width parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
gf712 committed Nov 5, 2019
1 parent 0b0de2e commit e9bced7
Show file tree
Hide file tree
Showing 13 changed files with 1,203 additions and 0 deletions.
Binary file added .RData
Binary file not shown.
15 changes: 15 additions & 0 deletions .Rhistory
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
dyn.load(paste("example", .Platform$dynlib.ext, sep=""))
source("example.R")
cacheMetaData(1)
source("test.R")
cacheMetaData(1)
m <- test:::Machine()
m <- Machine()
dyn.load(paste("test", .Platform$dynlib.ext, sep=""))
source("test.R")
cacheMetaData(1)
m <- Machine()
m
m:name()
m$name()
m$own()
22 changes: 22 additions & 0 deletions Base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
template <typename DerivedType>
class Base {
// int base1Param;
// int base2Param;
// public:
// Base() : base1Param(0) {}
// int getBase1Param() {
// return base1Param;
// }
// T& setBase1Param(int value) {
// base1Param = value;
// return *static_cast<T*>(this);
// }
// int getBase2Param() {
// return base2Param;
// }
// T& setBase2Param(int value) {
// base2Param = value;
// return *static_cast<T*>(this);
// }
// virtual ~Base() {}
};
5 changes: 5 additions & 0 deletions Derived.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "Base.h"

template <typename T>
class Derived: public Base<Derived<T>> {};

4 changes: 4 additions & 0 deletions Interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "Derived.h"

class Interface: public Base<Derived>
{};
153 changes: 153 additions & 0 deletions src/shogun/kernel/Autodiff_benchmark.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#include <shogun/distance/EuclideanDistance.h>
#include <shogun/features/DenseFeatures.h>
#include <shogun/lib/SGMatrix.h>
#include <shogun/mathematics/linalg/LinalgNamespace.h>
#include <shogun/mathematics/UniformIntDistribution.h>

#include <benchmark/benchmark.h>
#include <stan/math/rev/scal.hpp>
#include <unsupported/Eigen/AutoDiff>

#include <random>

namespace shogun
{
static SGMatrix<float64_t> createRandomData(const benchmark::State& state)
{
std::random_device rd;
std::mt19937_64 prng(rd());
UniformIntDistribution<index_t> uniform_int_dist(0, 1);

index_t num_dim = state.range(1);
index_t num_vecs = state.range(0);

SGMatrix<float64_t> mat(num_dim, num_vecs);
for (index_t i=0; i<num_vecs; i++)
{
for (index_t j=0; j<num_dim; j++)
{
mat(j,i) = uniform_int_dist(prng) + 0.5;
}
}
return mat;
}

void BM_Autodiff(benchmark::State& state)
{
for (auto _ : state)
{
SGMatrix<float64_t> mat = createRandomData(state);

SGMatrix<float64_t> derivative=SGMatrix<float64_t>(state.range(0), state.range(1));
auto feat = new CDenseFeatures(mat);
auto dist = CEuclideanDistance(feat, feat);

stan::math::var x = 1.0;
stan::math::var log_width = 0.0;
auto f = exp(-x / exp(log_width * 2.0) * 2.0);

for (int k=0; k<state.range(1); k++)
{
for (int j=0; j<state.range(0); j++)
{
const double& tmp_const = x->val_;
double* tmp = const_cast<double*>(&tmp_const);
*tmp = dist.distance(j, k);
f.grad();
derivative(j, k) = log_width.adj();
stan::math::set_zero_all_adjoints();
}
}
}
}

void BM_Autodiff_eigen(benchmark::State& state)
{
for (auto _ : state)
{
using EigenScalar = Eigen::Matrix<double, 1, 1>;
SGMatrix<float64_t> mat = createRandomData(state);

SGMatrix<float64_t> derivative=SGMatrix<float64_t>(state.range(0), state.range(1));
auto feat = new CDenseFeatures(mat);
auto dist = CEuclideanDistance(feat, feat);

Eigen::AutoDiffScalar<EigenScalar> eigen_log_width = 0.0;
eigen_log_width.derivatives() = Eigen::VectorXd::Unit(1,0);

for (int k=0; k<state.range(1); k++)
{
for (int j=0; j<state.range(0); j++)
{
auto x = dist.distance(j, k);
Eigen::AutoDiffScalar<EigenScalar> kernel = exp(-x / exp(eigen_log_width * 2.0) * 2.0);
derivative(j, k) = kernel.derivatives()(0);
}
}
}
}

// struct SE {
// const Eigen::Matrix<stan::math::var,Eigen::Dynamic,Eigen::Dynamic>& dist_;
// SE(const Eigen::Matrix<stan::math::var,Eigen::Dynamic,Eigen::Dynamic>& dist): dist_(dist) {}
// template <typename T>
// T operator(const )
// }

// void BM_Autodiff_vectorized(benchmark::State& state)
// {
// for (auto _ : state)
// {
// SGMatrix<float64_t> mat = createRandomData(state);

// SGMatrix<float64_t> derivative=SGMatrix<float64_t>(state.range(0), state.range(1));
// auto feat = new CDenseFeatures(mat);
// auto dist = CEuclideanDistance(feat, feat);
// Eigen::Matrix<stan::math::var,Eigen::Dynamic,Eigen::Dynamic> dist_var(state.range(0), state.range(1));
// for (int j=0; j<state.range(0); j++)
// for (int k=0; k<state.range(1); k++)
// dist_var(j, k) = dist.distance(j, k);

// Eigen::Matrix<stan::math::var,Eigen::Dynamic,Eigen::Dynamic> log_width(state.range(0), state.range(1));
// auto constant_part = exp(log_width * 2.0) * 2.0;
// auto gk = -dist_var / constant_part;
// gk.grad();

// for (int k=0; k<state.range(1); k++)
// {
// for (int j=0; j<state.range(0); j++)
// {
// derivative(j, k) = log_width(j, k).adj();
// }
// }
// }
// }

void BM_Manualdiff(benchmark::State& state)
{
for (auto _ : state)
{
SGMatrix<float64_t> mat = createRandomData(state);
auto feat = new CDenseFeatures(mat);
auto dist = CEuclideanDistance(feat, feat);
auto width = std::exp(0.0 * 2.0) * 2.0;

SGMatrix<float64_t> derivative=SGMatrix<float64_t>(state.range(0), state.range(1));

for (int k=0; k<state.range(1); k++)
{
#pragma omp parallel for
for (int j=0; j<state.range(0); j++)
{
auto el = dist.distance(j, k) / width;
derivative(j, k) = std::exp(-el) * el * 2.0;
}
}
}
}
}

BENCHMARK(BM_Autodiff)->RangeMultiplier(4)->Ranges({{64, 2<<10}, {4, 16}})->Unit(benchmark::kMillisecond);
BENCHMARK(BM_Autodiff_eigen)->RangeMultiplier(4)->Ranges({{64, 2<<10}, {4, 16}})->Unit(benchmark::kMillisecond);
// BENCHMARK(BM_Autodiff_vectorized)->RangeMultiplier(4)->Ranges({{64, 2<<10}, {4, 16}})->Unit(benchmark::kMillisecond);
BENCHMARK(BM_Manualdiff)->RangeMultiplier(4)->Ranges({{64, 2<<10}, {4, 16}})->Unit(benchmark::kMillisecond);
11 changes: 11 additions & 0 deletions src/shogun/kernel/GaussianKernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
#include <shogun/features/DotFeatures.h>
#include <shogun/distance/EuclideanDistance.h>
#include <shogun/mathematics/Math.h>
<<<<<<< HEAD
#include <stan/math/rev/scal.hpp>
=======
#include <stan/math.hpp>
>>>>>>> autodiff gaussian width parameter

using namespace shogun;

Expand Down Expand Up @@ -108,10 +112,17 @@ SGMatrix<float64_t> CGaussianKernel::get_parameter_gradient(const TParameter* pa
#pragma omp parallel for
for (int j=0; j<num_lhs; j++)
{
<<<<<<< HEAD
auto f = exp(-CShiftInvariantKernel::distance(j, k) / constant_part);
f.grad();
derivative(j, k) = log_width.adj();
stan::math::set_zero_all_adjoints();
=======
stan::math::var log_width = m_log_width;
auto f = exp(-CShiftInvariantKernel::distance(j, k) / (exp(log_width * 2.0) * 2.0));
f.grad();
derivative(j, k) = log_width.adj();
>>>>>>> autodiff gaussian width parameter
}
}
return derivative;
Expand Down

0 comments on commit e9bced7

Please sign in to comment.