LOG(ERROR) << "Curand not available. Skipping setting the curand seed.";
}
// RNG seed
- Get().random_generator_ = RNG(seed);
+ Get().random_generator_.reset(new RNG(seed));
+}
+
+void Caffe::set_generator(const void* other_rng) {
+ Get().random_generator_->set_generator(other_rng);
}
void Caffe::SetDevice(const int device_id) {
class Caffe::RNG::Generator {
public:
- caffe::rng_t rng;
+ Generator() : rng_(new caffe::rng_t(cluster_seedgen())) {}
+ explicit Generator(unsigned int seed) : rng_(new caffe::rng_t(seed)) {}
+ explicit Generator(const caffe::rng_t& other) :
+ rng_(new caffe::rng_t(other)) {}
+ shared_ptr<caffe::rng_t> rng_;
};
-Caffe::RNG::RNG()
-: generator_(new Generator) {
- generator_->rng = caffe::rng_t(cluster_seedgen());
-}
-
-Caffe::RNG::RNG(unsigned int seed)
-: generator_(new Generator) {
- generator_->rng = caffe::rng_t(seed);
-}
+Caffe::RNG::RNG() : generator_(new Generator) { }
-Caffe::RNG::~RNG() { delete generator_; }
+Caffe::RNG::RNG(unsigned int seed) : generator_(new Generator(seed)) { }
-Caffe::RNG::RNG(const RNG& other) : generator_(new Generator) {
- *generator_ = *other.generator_;
-}
+Caffe::RNG::RNG(const RNG& other) : generator_(new Generator(*other.generator_))
+ { }
Caffe::RNG& Caffe::RNG::operator=(const RNG& other) {
- *generator_ = *other.generator_;
+ generator_.reset(other.generator_.get());
return *this;
}
-void* Caffe::RNG::generator() {
- return &generator_->rng;
+const void* Caffe::RNG::generator() const {
+ return static_cast<const void*>(generator_->rng_.get());
}
-const void* Caffe::RNG::generator() const {
- return &generator_->rng;
+void Caffe::RNG::set_generator(const void* other_rng) {
+ const caffe::rng_t& rng = *static_cast<const caffe::rng_t*>(other_rng);
+ return generator_.reset(new Generator(rng));
}
const char* cublasGetErrorString(cublasStatus_t error) {
TypeParam mu = 0;
TypeParam sigma = 1;
caffe_vRngGaussian(sample_size,
- reinterpret_cast<TypeParam*>(data_a.mutable_cpu_data()), mu, sigma);
+ static_cast<TypeParam*>(data_a.mutable_cpu_data()), mu, sigma);
TypeParam true_mean = mu;
TypeParam true_std = sigma;
TypeParam bound = this->mean_bound(true_std, sample_size);
TypeParam empirical_mean =
- this->sample_mean(reinterpret_cast<const TypeParam*>(data_a.cpu_data()),
+ this->sample_mean(static_cast<const TypeParam*>(data_a.cpu_data()),
sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
}
TypeParam lower = 0;
TypeParam upper = 1;
caffe_vRngUniform(sample_size,
- reinterpret_cast<TypeParam*>(data_a.mutable_cpu_data()), lower, upper);
+ static_cast<TypeParam*>(data_a.mutable_cpu_data()), lower, upper);
TypeParam true_mean = (lower + upper) / 2;
TypeParam true_std = (upper - lower) / sqrt(12);
TypeParam bound = this->mean_bound(true_std, sample_size);
TypeParam empirical_mean =
- this->sample_mean(reinterpret_cast<const TypeParam*>(data_a.cpu_data()),
+ this->sample_mean(static_cast<const TypeParam*>(data_a.cpu_data()),
sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
}
// Sample from 0 mean Gaussian
TypeParam mu = 0;
TypeParam sigma = 1;
- caffe_vRngGaussian(sample_size, reinterpret_cast<TypeParam*>(
+ caffe_vRngGaussian(sample_size, static_cast<TypeParam*>(
gaussian_data.mutable_cpu_data()), mu, sigma);
TypeParam true_mean = mu;
TypeParam true_std = sigma;
TypeParam bound = this->mean_bound(true_std, sample_size);
TypeParam empirical_mean = this->sample_mean(
- reinterpret_cast<const TypeParam*>(gaussian_data.cpu_data()),
+ static_cast<const TypeParam*>(gaussian_data.cpu_data()),
sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
int num_pos = 0;
// Sample from Bernoulli with p = 0.3
p = 0.3;
caffe_vRngBernoulli(sample_size,
- reinterpret_cast<int*>(bernoulli_data.mutable_cpu_data()), p);
+ static_cast<int*>(bernoulli_data.mutable_cpu_data()), p);
true_mean = p;
true_std = sqrt(p * (1 - p));
bound = this->mean_bound(true_std, sample_size);
int num_ones = 0;
int num_other = 0;
const int* bernoulli_samples =
- reinterpret_cast<const int*>(bernoulli_data.cpu_data());
+ static_cast<const int*>(bernoulli_data.cpu_data());
for (int i = 0; i < sample_size; ++i) {
if (bernoulli_samples[i] == 0) {
++bernoulli_num_zeros;
LOG(INFO) << "Bernoulli: zeros: " << bernoulli_num_zeros
<< "; ones: " << num_ones << "; other: " << num_other;
EXPECT_EQ(0, num_other);
- EXPECT_EQ(sample_size * empirical_mean, num_ones);
- EXPECT_EQ(sample_size * (1.0 - empirical_mean), bernoulli_num_zeros);
+ TypeParam epsilon = 1e-4;
+ EXPECT_NEAR(sample_size * empirical_mean, num_ones, epsilon);
+ EXPECT_NEAR(sample_size * (1.0 - empirical_mean), bernoulli_num_zeros,
+ epsilon);
// Multiply Gaussian by Bernoulli
for (int i = 0; i < sample_size; ++i) {
samples[i] *= bernoulli_samples[i];
// Sample from Uniform on [-1, 1]
TypeParam a = -1;
TypeParam b = 1;
- caffe_vRngUniform(sample_size, reinterpret_cast<TypeParam*>(
+ caffe_vRngUniform(sample_size, static_cast<TypeParam*>(
uniform_data.mutable_cpu_data()), a, b);
TypeParam true_mean = (a + b) / 2;
TypeParam true_std = (b - a) / sqrt(12);
TypeParam bound = this->mean_bound(true_std, sample_size);
TypeParam empirical_mean = this->sample_mean(
- reinterpret_cast<const TypeParam*>(uniform_data.cpu_data()),
+ static_cast<const TypeParam*>(uniform_data.cpu_data()),
sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
int num_pos = 0;
// improbable), and roughly half positives and half negatives (with bound
// computed from a Bernoulli with p = 0.5).
EXPECT_EQ(0, num_zeros);
- double p = 0.5;
+ TypeParam p = 0.5;
true_mean = p;
true_std = sqrt(p * (1 - p));
bound = this->mean_bound(true_std, sample_size);
// Sample from Bernoulli with p = 0.3
p = 0.3;
caffe_vRngBernoulli(sample_size,
- reinterpret_cast<int*>(bernoulli_data.mutable_cpu_data()), p);
+ static_cast<int*>(bernoulli_data.mutable_cpu_data()), p);
true_mean = p;
true_std = sqrt(p * (1 - p));
bound = this->mean_bound(true_std, sample_size);
int num_ones = 0;
int num_other = 0;
const int* bernoulli_samples =
- reinterpret_cast<const int*>(bernoulli_data.cpu_data());
+ static_cast<const int*>(bernoulli_data.cpu_data());
for (int i = 0; i < sample_size; ++i) {
if (bernoulli_samples[i] == 0) {
++bernoulli_num_zeros;
LOG(INFO) << "Bernoulli: zeros: " << bernoulli_num_zeros
<< "; ones: " << num_ones << "; other: " << num_other;
EXPECT_EQ(0, num_other);
- EXPECT_EQ(sample_size * empirical_mean, num_ones);
- EXPECT_EQ(sample_size * (1.0 - empirical_mean), bernoulli_num_zeros);
+ TypeParam epsilon = 1e-4;
+ EXPECT_NEAR(sample_size * empirical_mean, num_ones, epsilon);
+ EXPECT_NEAR(sample_size * (1.0 - empirical_mean), bernoulli_num_zeros,
+ epsilon);
// Multiply Uniform by Bernoulli
for (int i = 0; i < sample_size; ++i) {
samples[i] *= bernoulli_samples[i];
SyncedMemory bernoulli1_data(sample_size * sizeof(int));
SyncedMemory bernoulli2_data(sample_size * sizeof(int));
Caffe::set_random_seed(1701);
- double p1 = 0.5;
- caffe_vRngBernoulli(sample_size, reinterpret_cast<int*>(
+ TypeParam p1 = 0.5;
+ caffe_vRngBernoulli(sample_size, static_cast<int*>(
bernoulli1_data.mutable_cpu_data()), p1);
TypeParam empirical_mean = this->sample_mean(
- reinterpret_cast<const int*>(bernoulli1_data.cpu_data()),
+ static_cast<const int*>(bernoulli1_data.cpu_data()),
sample_size);
int bernoulli1_num_zeros = 0;
int num_ones = 0;
int num_other = 0;
int* bernoulli_samples =
- reinterpret_cast<int*>(bernoulli1_data.mutable_cpu_data());
+ static_cast<int*>(bernoulli1_data.mutable_cpu_data());
for (int i = 0; i < sample_size; ++i) {
if (bernoulli_samples[i] == 0) {
++bernoulli1_num_zeros;
<< "; sample mean = " << empirical_mean;
LOG(INFO) << "Bernoulli1: zeros: " << bernoulli1_num_zeros
<< "; ones: " << num_ones << "; other: " << num_other;
- empirical_mean =
- this->sample_mean((const int *)bernoulli2_data.cpu_data(), sample_size);
+ empirical_mean = this->sample_mean(
+ static_cast<const int*>(bernoulli1_data.cpu_data()), sample_size);
EXPECT_NEAR(empirical_mean, true_mean, bound);
EXPECT_EQ(num_other, 0);
// Sample from Bernoulli with p = 0.3
- double p = 0.3;
- caffe_vRngBernoulli(sample_size,
- reinterpret_cast<int*>(bernoulli2_data.mutable_cpu_data()), p);
+ TypeParam p = 0.3;
+ caffe_vRngBernoulli(sample_size, static_cast<int*>(
+ bernoulli2_data.mutable_cpu_data()), p);
true_mean = p;
true_std = sqrt(p * (1 - p));
bound = this->mean_bound(true_std, sample_size);
- empirical_mean =
- this->sample_mean((const int *)bernoulli2_data.cpu_data(), sample_size);
+ empirical_mean = this->sample_mean(
+ static_cast<const int*>(bernoulli2_data.cpu_data()), sample_size);
LOG(INFO) << "Bernoulli2: Expected mean = " << true_mean
<< "; sample mean = " << empirical_mean;
EXPECT_NEAR(empirical_mean, true_mean, bound);
num_ones = 0;
num_other = 0;
const int* bernoulli2_samples =
- reinterpret_cast<const int*>(bernoulli2_data.cpu_data());
+ static_cast<const int*>(bernoulli2_data.cpu_data());
for (int i = 0; i < sample_size; ++i) {
if (bernoulli2_samples[i] == 0) {
++bernoulli2_num_zeros;
LOG(INFO) << "Bernoulli2: zeros: " << bernoulli2_num_zeros
<< "; ones: " << num_ones << "; other: " << num_other;
EXPECT_EQ(0, num_other);
- EXPECT_EQ(sample_size * empirical_mean, num_ones);
- EXPECT_EQ(sample_size * (1.0 - empirical_mean), bernoulli2_num_zeros);
+ TypeParam epsilon = 1e-4;
+ EXPECT_NEAR(sample_size * empirical_mean, num_ones, epsilon);
+ EXPECT_NEAR(sample_size * (1.0 - empirical_mean), bernoulli2_num_zeros,
+ epsilon);
// Multiply Bernoulli1 by Bernoulli2
for (int i = 0; i < sample_size; ++i) {
bernoulli_samples[i] *= bernoulli2_samples[i];
p *= p1;
true_mean = p;
true_std = sqrt(p * (1 - p));
- empirical_mean =
- this->sample_mean((const int *)bernoulli2_data.cpu_data(), sample_size);
+ empirical_mean = this->sample_mean(
+ static_cast<const int *>(bernoulli2_data.cpu_data()), sample_size);
bound = this->mean_bound(true_std, sample_size);
LOG(INFO) << "Bernoulli1*Bernoulli2: Expected mean = " << true_mean
<< "; sample mean = " << empirical_mean;
CHECK_GE(n, 0);
CHECK(r);
CHECK_LE(a, b);
-
- boost::uniform_real<Dtype> random_distribution(
- a, caffe_nextafter<Dtype>(b));
- boost::variate_generator<caffe::rng_t,
- boost::uniform_real<Dtype> > variate_generator(
- caffe_rng(), random_distribution);
-
+ boost::uniform_real<Dtype> random_distribution(a, caffe_nextafter<Dtype>(b));
+ boost::variate_generator<caffe::rng_t, boost::uniform_real<Dtype> >
+ variate_generator(caffe_rng(), random_distribution);
for (int i = 0; i < n; ++i) {
r[i] = variate_generator();
}
+ caffe_set_rng(variate_generator.engine());
}
template
CHECK(r);
CHECK_GT(sigma, 0);
boost::normal_distribution<Dtype> random_distribution(a, sigma);
- boost::variate_generator<caffe::rng_t,
- boost::normal_distribution<Dtype> > variate_generator(
- caffe_rng(), random_distribution);
-
+ boost::variate_generator<caffe::rng_t, boost::normal_distribution<Dtype> >
+ variate_generator(caffe_rng(), random_distribution);
for (int i = 0; i < n; ++i) {
r[i] = variate_generator();
}
+ caffe_set_rng(variate_generator.engine());
}
template
const double sigma);
template <typename Dtype>
-void caffe_vRngBernoulli(const int n, Dtype* r, const double p) {
+void caffe_vRngBernoulli(const int n, int* r, const Dtype p) {
CHECK_GE(n, 0);
CHECK(r);
CHECK_GE(p, 0);
CHECK_LE(p, 1);
- boost::bernoulli_distribution<double> random_distribution(p);
- boost::variate_generator<caffe::rng_t,
- boost::bernoulli_distribution<double> > variate_generator(
- caffe_rng(), random_distribution);
-
+ boost::bernoulli_distribution<Dtype> random_distribution(p);
+ boost::variate_generator<caffe::rng_t, boost::bernoulli_distribution<Dtype> >
+ variate_generator(caffe_rng(), random_distribution);
for (int i = 0; i < n; ++i) {
r[i] = variate_generator();
}
+ caffe_set_rng(variate_generator.engine());
}
template
-void caffe_vRngBernoulli<int>(const int n, int* r, const double p);
+void caffe_vRngBernoulli<double>(const int n, int* r, const double p);
+
+template
+void caffe_vRngBernoulli<float>(const int n, int* r, const float p);
template <>
float caffe_cpu_dot<float>(const int n, const float* x, const float* y) {