Add BlobMathTest with unit tests for sumsq and asum
authorJeff Donahue <jeff.donahue@gmail.com>
Fri, 30 Jan 2015 03:07:12 +0000 (19:07 -0800)
committerJeff Donahue <jeff.donahue@gmail.com>
Fri, 30 Jan 2015 03:07:49 +0000 (19:07 -0800)
src/caffe/test/test_blob.cpp

index adf7a4d..c619ad1 100644 (file)
@@ -54,4 +54,117 @@ TYPED_TEST(BlobSimpleTest, TestReshape) {
   EXPECT_EQ(this->blob_->count(), 120);
 }
 
+template <typename TypeParam>
+class BlobMathTest : public MultiDeviceTest<TypeParam> {
+  typedef typename TypeParam::Dtype Dtype;
+ protected:
+  BlobMathTest()
+      : blob_(new Blob<Dtype>(2, 3, 4, 5)) {}
+  virtual ~BlobMathTest() { delete blob_; }
+  Blob<Dtype>* const blob_;
+};
+
+TYPED_TEST_CASE(BlobMathTest, TestDtypesAndDevices);
+
+TYPED_TEST(BlobMathTest, TestSumOfSquares) {
+  typedef typename TypeParam::Dtype Dtype;
+
+  // Uninitialized Blob should have sum of squares == 0.
+  EXPECT_EQ(0, this->blob_->sumsq_data());
+  EXPECT_EQ(0, this->blob_->sumsq_diff());
+  FillerParameter filler_param;
+  filler_param.set_min(-3);
+  filler_param.set_max(3);
+  UniformFiller<Dtype> filler(filler_param);
+  filler.Fill(this->blob_);
+  Dtype expected_sumsq = 0;
+  const Dtype* data = this->blob_->cpu_data();
+  for (int i = 0; i < this->blob_->count(); ++i) {
+    expected_sumsq += data[i] * data[i];
+  }
+  // Do a mutable access on the current device,
+  // so that the sumsq computation is done on that device.
+  // (Otherwise, this would only check the CPU sumsq implementation.)
+  switch (TypeParam::device) {
+  case Caffe::CPU:
+    this->blob_->mutable_cpu_data();
+    break;
+  case Caffe::GPU:
+    this->blob_->mutable_gpu_data();
+    break;
+  default:
+    LOG(FATAL) << "Unknown device: " << TypeParam::device;
+  }
+  EXPECT_FLOAT_EQ(expected_sumsq, this->blob_->sumsq_data());
+  EXPECT_EQ(0, this->blob_->sumsq_diff());
+
+  // Check sumsq_diff too.
+  const Dtype kDiffScaleFactor = 7;
+  caffe_cpu_scale(this->blob_->count(), kDiffScaleFactor, data,
+                  this->blob_->mutable_cpu_diff());
+  switch (TypeParam::device) {
+  case Caffe::CPU:
+    this->blob_->mutable_cpu_diff();
+    break;
+  case Caffe::GPU:
+    this->blob_->mutable_gpu_diff();
+    break;
+  default:
+    LOG(FATAL) << "Unknown device: " << TypeParam::device;
+  }
+  EXPECT_FLOAT_EQ(expected_sumsq, this->blob_->sumsq_data());
+  EXPECT_FLOAT_EQ(expected_sumsq * kDiffScaleFactor * kDiffScaleFactor,
+                  this->blob_->sumsq_diff());
+}
+
+TYPED_TEST(BlobMathTest, TestAsum) {
+  typedef typename TypeParam::Dtype Dtype;
+
+  // Uninitialized Blob should have sum of squares == 0.
+  EXPECT_EQ(0, this->blob_->asum_data());
+  EXPECT_EQ(0, this->blob_->asum_diff());
+  FillerParameter filler_param;
+  filler_param.set_min(-3);
+  filler_param.set_max(3);
+  UniformFiller<Dtype> filler(filler_param);
+  filler.Fill(this->blob_);
+  Dtype expected_asum = 0;
+  const Dtype* data = this->blob_->cpu_data();
+  for (int i = 0; i < this->blob_->count(); ++i) {
+    expected_asum += std::fabs(data[i]);
+  }
+  // Do a mutable access on the current device,
+  // so that the asum computation is done on that device.
+  // (Otherwise, this would only check the CPU asum implementation.)
+  switch (TypeParam::device) {
+  case Caffe::CPU:
+    this->blob_->mutable_cpu_data();
+    break;
+  case Caffe::GPU:
+    this->blob_->mutable_gpu_data();
+    break;
+  default:
+    LOG(FATAL) << "Unknown device: " << TypeParam::device;
+  }
+  EXPECT_FLOAT_EQ(expected_asum, this->blob_->asum_data());
+  EXPECT_EQ(0, this->blob_->asum_diff());
+
+  // Check asum_diff too.
+  const Dtype kDiffScaleFactor = 7;
+  caffe_cpu_scale(this->blob_->count(), kDiffScaleFactor, data,
+                  this->blob_->mutable_cpu_diff());
+  switch (TypeParam::device) {
+  case Caffe::CPU:
+    this->blob_->mutable_cpu_diff();
+    break;
+  case Caffe::GPU:
+    this->blob_->mutable_gpu_diff();
+    break;
+  default:
+    LOG(FATAL) << "Unknown device: " << TypeParam::device;
+  }
+  EXPECT_FLOAT_EQ(expected_asum, this->blob_->asum_data());
+  EXPECT_FLOAT_EQ(expected_asum * kDiffScaleFactor, this->blob_->asum_diff());
+}
+
 }  // namespace caffe