New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vectorized RNG #4437
Vectorized RNG #4437
Changes from 5 commits
424e61e
0c59ece
8c7fe7f
e0bd50e
62c88cd
823e70d
6a97846
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,13 +11,16 @@ | |
|
||
#include <shogun/base/macros.h> | ||
#include <shogun/io/SGIO.h> | ||
#include <shogun/lib/config.h> | ||
#include <shogun/lib/SGReferencedData.h> | ||
#include <shogun/lib/common.h> | ||
#include <shogun/lib/config.h> | ||
#include <shogun/mathematics/Random.h> | ||
#include <shogun/util/iterators.h> | ||
#include <shogun/lib/SGReferencedData.h> | ||
|
||
#include <memory> | ||
#include "sg_type_traits.h" | ||
#include <atomic> | ||
#include <memory> | ||
#include <algorithm> | ||
|
||
namespace Eigen | ||
{ | ||
|
@@ -306,9 +309,60 @@ template<class T> class SGMatrix : public SGReferencedData | |
/** Set matrix to a constant */ | ||
void set_const(T const_elem); | ||
|
||
/** fill matrix with zeros */ | ||
/** Fill matrix with zeros */ | ||
void zero(); | ||
|
||
/** | ||
iglesias marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* Fill matrix with uniformly distributed randoms | ||
* Float Types: [0, 1) | ||
* Int Types: std::numeric_limit<T>::(min->max) | ||
**/ | ||
template <typename U> | ||
using enable_simd_float = std::enable_if_t<sg_is_same_v<U, float64_t>>; | ||
template <typename U = T> | ||
auto random() -> enable_simd_float<U> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. separating declaration and definition would need explicit specialization of each template method signature - which would end up being really long. Since the methods are relatively short it seemed ok to keep both in the header file. The only disadvantage is that an additional include of Math.h has to be added here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So is this the same as writing:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep - Actually 3 versions are possible which mean the same:
Mine is a slightly more readable version of (2) :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK! It is more readable indeed! Why do you need the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SFINAE only works on templated functions. A method inside a template class doesnt count. The function itself has to also be templated. As mentioned in CPPReference There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Btw I wrote up a short blog post on this topic - more as a point of reference but here it is in case anyone is interested :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah true! Thanks, I'll have a look! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah cool! |
||
{ | ||
auto r = std::make_unique<CRandom>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the problem with having CRandom created here is that you wont ever be able to set seed :( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the rest of the patch has the same pattern and it'll be a problem as well there... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ive addressed it for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice! |
||
r->fill_array_co(matrix, num_rows * num_cols); | ||
} | ||
|
||
template <typename U> | ||
using enable_simd_int = | ||
std::enable_if_t<sg_is_any_of_v<U, uint32_t, uint64_t>>; | ||
template <typename U = T> | ||
auto random() -> enable_simd_int<U> | ||
{ | ||
auto r = std::make_unique<CRandom>(); | ||
r->fill_array(matrix, num_rows * num_cols); | ||
} | ||
|
||
template <typename U> | ||
using enable_nonsimd_float = | ||
std::enable_if_t<sg_is_any_of_v<U, float32_t, floatmax_t>>; | ||
template <typename U = T> | ||
auto random() -> enable_nonsimd_float<U> | ||
{ | ||
auto r = std::make_unique<CRandom>(); | ||
// Casting floats upwards or downwards is safe | ||
// Ref: https://stackoverflow.com/a/36840390/3656081 | ||
std::transform(matrix, matrix + (num_rows*num_cols), matrix, | ||
[&r](auto){ return r->random_half_open(); }); | ||
} | ||
|
||
template <typename U> | ||
using enable_nonsimd_int = | ||
std::enable_if_t<sg_is_any_of_v<U, int8_t, uint8_t, int16_t, uint16_t, | ||
int32_t, int64_t>>; | ||
template <typename U = T> | ||
auto random() -> enable_nonsimd_int<U> | ||
{ | ||
auto r = std::make_unique<CRandom>(); | ||
std::transform(matrix, matrix + (num_rows*num_cols), matrix, | ||
[&r](auto){ return r->random( | ||
std::numeric_limits<T>::min(), | ||
std::numeric_limits<T>::max()); }); | ||
} | ||
|
||
/** | ||
* Checks whether the matrix is symmetric or not. The equality check | ||
* is performed using '==' operators for discrete types (int, char, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* This software is distributed under BSD 3-clause license (see LICENSE file). | ||
* | ||
* Authors: Saatvik Shah | ||
*/ | ||
|
||
#include <type_traits> | ||
|
||
#ifndef SHOGUN_SG_TYPE_TRAITS_H | ||
#define SHOGUN_SG_TYPE_TRAITS_H | ||
/** | ||
* A collection of useful type traits | ||
*/ | ||
|
||
namespace shogun { | ||
template <typename T1, typename T2> | ||
constexpr bool sg_is_same_v = std::is_same<T1, T2>::value; | ||
// Checks if any one of the types matches | ||
// Ref: https://stackoverflow.com/a/17032517/3656081 | ||
template<typename T, typename... Rest> | ||
struct sg_is_any_of : std::false_type { | ||
}; | ||
|
||
template<typename T, typename First> | ||
struct sg_is_any_of<T, First> : std::is_same<T, First> { | ||
}; | ||
|
||
template<typename T, typename First, typename... Rest> | ||
struct sg_is_any_of<T, First, Rest...> | ||
: std::integral_constant<bool, std::is_same<T, First>::value || | ||
sg_is_any_of<T, Rest...>::value> { | ||
}; | ||
|
||
template<typename T, typename First, typename... Rest> | ||
constexpr bool sg_is_any_of_v = sg_is_any_of<T, First, Rest...>::value; | ||
|
||
// all shogun base classes for put/add templates | ||
class CMachine; | ||
class CKernel; | ||
class CDistance; | ||
class CFeatures; | ||
class CLabels; | ||
class CECOCEncoder; | ||
class CECOCDecoder; | ||
class CMulticlassStrategy; | ||
class CNeuralLayer; | ||
// type trait to enable certain methods only for shogun base types | ||
template<class T> | ||
struct is_sg_base | ||
: std::integral_constant<bool, | ||
sg_is_any_of_v<T, CMachine, CKernel, | ||
CDistance, CFeatures, | ||
CLabels, CECOCEncoder, | ||
CECOCDecoder, CMulticlassStrategy, | ||
CNeuralLayer>> { | ||
}; | ||
} | ||
#endif // SHOGUN_SG_TYPE_TRAITS_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,22 @@ | |
|
||
using namespace shogun; | ||
|
||
TEST(SGMatrixTest, vectorized_rng) | ||
{ | ||
auto rng_check_float = [](auto elem) { | ||
SGMatrix<decltype(elem)> sg_mat(10, 5); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would there be a away to check it against the individual calling of random with some seed fixing magic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. might be a bit of a chore to implement - especially because I'd have to based on the type use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah don't worry then |
||
sg_mat.random(); | ||
for (int i = 0; i < sg_mat.size(); i++) | ||
{ | ||
EXPECT_LE(0.0, sg_mat[i]); | ||
EXPECT_GT(1.0, sg_mat[i]); | ||
} | ||
}; | ||
rng_check_float(float32_t{0.0}); | ||
rng_check_float(float64_t{0.0}); | ||
rng_check_float(floatmax_t{0.0}); | ||
} | ||
|
||
TEST(SGMatrixTest,ctor_zero_const) | ||
{ | ||
SGMatrix<float64_t> a(10, 5); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unneeded - will revert