diff --git a/paddle/math/tests/CMakeLists.txt b/paddle/math/tests/CMakeLists.txt index d593fe0fa3975db105c484a58bbccd3313bf36f1..893597b158750876c307defc87d55c8fa1a10173 100644 --- a/paddle/math/tests/CMakeLists.txt +++ b/paddle/math/tests/CMakeLists.txt @@ -2,7 +2,7 @@ add_simple_unittest(test_ExecViaCpu) add_simple_unittest(test_SIMDFunctions) -add_simple_unittest(test_matrix) +add_simple_unittest(test_SparseMatrix) # TODO(yuyang18): Refactor TestUtil.cpp. Remove this cross module reference. add_unittest(test_matrixCompare @@ -14,5 +14,6 @@ add_simple_unittest(test_perturbation) add_simple_unittest(test_CpuGpuVector) add_simple_unittest(test_Allocator) add_simple_unittest(test_FPException) -add_simple_unittest(test_BaseMatrix) add_simple_unittest(test_GpuProfiler) +add_simple_unittest(test_BaseMatrix) +add_simple_unittest(test_Matrix) diff --git a/paddle/math/tests/TensorCheck.h b/paddle/math/tests/TensorCheck.h index f19933d1f6bc36868362c59312d5c46b41489995..d4821314f3beafb2cdb8f00da8fa60a1b5dc9141 100644 --- a/paddle/math/tests/TensorCheck.h +++ b/paddle/math/tests/TensorCheck.h @@ -37,6 +37,7 @@ public: } } } + return true; } @@ -61,7 +62,7 @@ template <> class CopyToCpu { public: explicit CopyToCpu(const GpuMatrix& arg) - : arg_(arg.getHeight(), arg.getWidth()) { + : arg_(arg.getHeight(), arg.getWidth()) { arg_.copyFrom(arg); } CpuMatrix& copiedArg() { return arg_; } @@ -70,7 +71,7 @@ private: CpuMatrix arg_; }; -template +template void TensorCheck(AssertEq compare, const CpuMatrix& matrix1, const CpuMatrix& matrix2) { @@ -94,15 +95,19 @@ void TensorCheck(AssertEq compare, EXPECT_EQ(count, 0) << "There are " << count << " different element."; } -template +template extern void TensorCheck(AssertEq compare, const Tensor1& tensor1, const Tensor2& tensor2) { - TensorCheck( - compare, - CopyToCpu(tensor1).copiedArg(), - CopyToCpu(tensor2).copiedArg()); + TensorCheck(compare, + CopyToCpu(tensor1).copiedArg(), + CopyToCpu(tensor2).copiedArg()); } -} // namespace autotest +template +void TensorCheck(AssertEq compare, real args1, real args2) { + EXPECT_EQ(compare(args1, args2), true) << "[Test error] args1 = " << args1 + << ", args2 = " << args2; +} +} // namespace autotest diff --git a/paddle/math/tests/TestUtils.h b/paddle/math/tests/TestUtils.h index ffd113454277b02c35aba5d654d885bd9d70a0fe..96ba2c38c8d4c4fb37fa34fe3d86a07d42a9535a 100644 --- a/paddle/math/tests/TestUtils.h +++ b/paddle/math/tests/TestUtils.h @@ -12,7 +12,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ - /** * TestUtils.h is used to automatically compare CPU and GPU code is consistent. * @@ -21,7 +20,7 @@ limitations under the License. */ * a. void BaseMatrix::tanh(BaseMatrixT& b); * Compare method: BaseMatrixCompare<0>(&BaseMatrix::tanh); * - * b. + * b. * */ @@ -33,102 +32,169 @@ using namespace paddle; // NOLINT namespace autotest { -template +template class ReplaceType { public: typedef T1 type; }; -template<> +template <> class ReplaceType { public: typedef CpuMatrix type; }; -template<> +template <> class ReplaceType { public: typedef GpuMatrix type; }; +template <> +class ReplaceType { +public: + typedef CpuMatrix type; +}; + +template <> +class ReplaceType { +public: + typedef GpuMatrix type; +}; + // construct a argument -template T construct(int height, int width); -template<> float construct(int height, int width) { return 0.0; } -template<> CpuMatrix construct(int height, int width) { +template +T construct(int height, int width); +template <> +float construct(int height, int width) { + return 0.0; +} +template <> +CpuMatrix construct(int height, int width) { CpuMatrix a(height, width); return a; } -template<> GpuMatrix construct(int height, int width) { +template <> +GpuMatrix construct(int height, int width) { GpuMatrix a(height, width); return a; } // init a argument -template void init(T& v); -template<> void init(float& v) { v = 0.5; } -template<> void init(CpuMatrix& v) { v.randomizeUniform(); } -template<> void init(GpuMatrix& v) { v.randomizeUniform(); } +template +void init(T& v); +template <> +void init(float& v) { + v = 0.5; +} +template <> +void init(CpuMatrix& v) { + v.randomizeUniform(); +} +template <> +void init(GpuMatrix& v) { + v.randomizeUniform(); +} // init a tuple which contains a set of arguments. -template -inline typename std::enable_if::type -initTuple(std::tuple& t){} +template +inline typename std::enable_if::type initTuple( + std::tuple& t) {} -template -inline typename std::enable_if::type -initTuple(std::tuple& t) { +template + inline typename std::enable_if < + I::type initTuple(std::tuple& t) { init(std::get(t)); initTuple(t); } // copy a argument, copy src to dest -template void copy(T1& dest, T2& src); -template<> void copy(float& dest, float& src) { dest = src; } -template<> void copy(GpuMatrix& dest, CpuMatrix& src) { +template +void copy(T1& dest, T2& src); +template <> +void copy(float& dest, float& src) { + dest = src; +} +template <> +void copy(GpuMatrix& dest, CpuMatrix& src) { dest.copyFrom(src); } // copy a tuple, copy src to dest -template -inline typename std::enable_if::type -copyTuple(std::tuple& dest, std::tuple& src) {} - -template -inline typename std::enable_if::type -copyTuple(std::tuple& dest, std::tuple& src) { +template +inline typename std::enable_if::type copyTuple( + std::tuple& dest, std::tuple& src) {} + +template + inline typename std::enable_if < + I::type copyTuple(std::tuple& dest, + std::tuple& src) { copy(std::get(dest), std::get(src)); copyTuple(dest, src); } +// Compare output +template +inline typename std::enable_if::type checkTuple( + std::tuple& args1, + std::tuple& args2, + AssertEq compare) {} + +template + inline typename std::enable_if < + I::type checkTuple(std::tuple& args1, + std::tuple& args2, + AssertEq compare) { + TensorCheck(compare, std::get(args1), std::get(args2)); + checkTuple(args1, args2, compare); +} + // call member function template + typename FC, + typename R, + typename... FArgs, + typename... Args> R call(C& obj, R (FC::*f)(FArgs...), Args&&... args) { return (obj.*f)(args...); } -template -void BaseMatrixCompare(R (C::*f)(Args...), AssertEq compare) { +void BaseMatrixCompare(R (C::*f)(Args...), + AssertEq compare, + bool checkArgs = false) { for (auto height : {1, 11, 73, 128, 200, 330}) { for (auto width : {1, 3, 32, 100, 512, 1000}) { - CpuMatrix obj1(ApplyCol ? 1 : height, - ApplyRow ? 1 : width); - GpuMatrix obj2(ApplyCol ? 1 : height, - ApplyRow ? 1 : width); + CpuMatrix obj1(ApplyCol ? 1 : height, ApplyRow ? 1 : width); + GpuMatrix obj2(ApplyCol ? 1 : height, ApplyRow ? 1 : width); init(obj1); copy(obj2, obj1); auto tuple1 = std::make_tuple( - construct>::type>::type, - CpuMatrix>::type>(height, width)...); + construct>::type>::type, + CpuMatrix>::type>(height, width)...); auto tuple2 = std::make_tuple( - construct>::type>::type, - GpuMatrix>::type>(height, width)...); + construct>::type>::type, + GpuMatrix>::type>(height, width)...); initTuple(tuple1); copyTuple(tuple2, tuple1); @@ -137,16 +203,19 @@ void BaseMatrixCompare(R (C::*f)(Args...), AssertEq compare) { call(obj2, f, std::get(tuple2)...); TensorCheck(compare, obj1, obj2); + if (checkArgs) { + checkTuple(tuple1, tuple2, compare); + } } } } } // namespace autotest -template -void BaseMatrixCompare(R (C::*f)(Args...)) { +template +void BaseMatrixCompare(R (C::*f)(Args...), bool checkArgs = false) { static_assert(sizeof...(I) == sizeof...(Args), - "size of parameter packs are not equal"); + "size of parameter packs are not equal"); #ifndef PADDLE_TYPE_DOUBLE autotest::AssertEqual compare(1e-5); @@ -154,13 +223,13 @@ void BaseMatrixCompare(R (C::*f)(Args...)) { autotest::AssertEqual compare(1e-10); #endif - autotest::BaseMatrixCompare(f, compare); + autotest::BaseMatrixCompare(f, compare, checkArgs); } -template +template void BaseMatrixApplyRow(R (C::*f)(Args...)) { static_assert(sizeof...(I) == sizeof...(Args), - "size of parameter packs are not equal"); + "size of parameter packs are not equal"); #ifndef PADDLE_TYPE_DOUBLE autotest::AssertEqual compare(1e-3); @@ -171,10 +240,10 @@ void BaseMatrixApplyRow(R (C::*f)(Args...)) { autotest::BaseMatrixCompare(f, compare); } -template +template void BaseMatrixApplyCol(R (C::*f)(Args...)) { static_assert(sizeof...(I) == sizeof...(Args), - "size of parameter packs are not equal"); + "size of parameter packs are not equal"); #ifndef PADDLE_TYPE_DOUBLE autotest::AssertEqual compare(1e-3); @@ -183,4 +252,3 @@ void BaseMatrixApplyCol(R (C::*f)(Args...)) { #endif autotest::BaseMatrixCompare(f, compare); } - diff --git a/paddle/math/tests/test_Matrix.cpp b/paddle/math/tests/test_Matrix.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4d9d34976b9c6a0c59760cdc62b39a56d82e347 --- /dev/null +++ b/paddle/math/tests/test_Matrix.cpp @@ -0,0 +1,49 @@ +/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. */ + +#ifndef PADDLE_ONLY_CPU +/** + * This test file compares the implementation of CPU and GPU function + * in Matrix.cpp. + */ + +#include +#include "paddle/utils/Util.h" +#include "paddle/math/BaseMatrix.h" +#include "TestUtils.h" + +using namespace paddle; // NOLINT +using namespace std; // NOLINT + +/** + * Test member functions which prototype is + * void (Matrix::*)(Matrix&). + */ +TEST(BaseMatrix, real) { + typedef void (Matrix::*FunctionProto)(Matrix&); +#define MATRIXCOMPARE(function) \ + BaseMatrixCompare<0>(static_cast(&Matrix::function), true); + + MATRIXCOMPARE(softmax); + +#undef MATRIXCOMPARE +} + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + initMain(argc, argv); + return RUN_ALL_TESTS(); +} + +#endif diff --git a/paddle/math/tests/test_matrixCompare.cpp b/paddle/math/tests/test_matrixCompare.cpp index 8f96672b88e7c40d615bc316b61604538714ddc9..80596abe8210dfe0d3accbaecf8d078fe5e49b6b 100644 --- a/paddle/math/tests/test_matrixCompare.cpp +++ b/paddle/math/tests/test_matrixCompare.cpp @@ -693,24 +693,6 @@ TEST(Matrix, unary) { } } -void testMatrixSoftmax(int height, int width) { - MatrixPtr cpuInput = std::make_shared(height, width); - MatrixPtr cpuOutput = std::make_shared(height, width); - MatrixPtr gpuInput = std::make_shared(height, width); - MatrixPtr gpuOutput = std::make_shared(height, width); - - cpuInput->randomizeUniform(); - gpuInput->copyFrom(*cpuInput); - cpuOutput->zero(); - gpuOutput->zero(); - cpuInput->softmax(*cpuOutput); - gpuInput->softmax(*gpuOutput); - - MatrixPtr outputCheck = std::make_shared(height, width); - outputCheck->copyFrom(*gpuOutput); - MatrixCheckErr(*cpuOutput, *outputCheck); -} - void testSequenceSoftmax(int batchSize) { // forward int inputDim = 1; @@ -793,7 +775,6 @@ TEST(Matrix, softmax) { for (auto width : {1, 32, 100, 512, 1000}) { VLOG(3) << " height=" << height << " width=" << width; - testMatrixSoftmax(height, width); testMatrixSoftmaxBp(height, width); testMatrixSoftmaxThreshold(height, width); }