You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
213 lines
7.2 KiB
213 lines
7.2 KiB
/* Copyright (c) 2016 PaddlePaddle Authors. 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. */
|
|
|
|
#include <gtest/gtest.h>
|
|
#include "FunctionTest.h"
|
|
#include "paddle/math/Matrix.h"
|
|
#include "paddle/math/SparseMatrix.h"
|
|
#include "paddle/math/tests/test_matrixUtil.h"
|
|
#include "paddle/testing/TestUtil.h"
|
|
|
|
using namespace paddle; // NOLINT
|
|
|
|
/**
|
|
* C += A * B, A, B, C dense matrix
|
|
* dense = dense * dense
|
|
*/
|
|
void testFuncDDDMatrix(
|
|
bool transa, bool transb, size_t dimM, size_t dimN, size_t dimK) {
|
|
real scaleT = 1.0;
|
|
size_t heightA = (transa == false) ? dimM : dimK;
|
|
size_t widthA = (transa == false) ? dimK : dimM;
|
|
size_t heightB = (transb == false) ? dimK : dimN;
|
|
size_t widthB = (transb == false) ? dimN : dimK;
|
|
size_t heightC = dimM;
|
|
size_t widthC = dimN;
|
|
// init Test object
|
|
FunctionCompare test(
|
|
"MulOp", FuncConfig().set("aTrans", transa).set("bTrans", transb));
|
|
// prepare input arguments
|
|
/// matrix A : HA * WA
|
|
test.addInputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{heightA, widthA}));
|
|
/// matrix B: HB * WB
|
|
test.addInputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{heightB, widthB}));
|
|
|
|
/// output matrix C: HC * WC
|
|
test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{heightC, widthC}),
|
|
scaleT == 1.0 ? ADD_TO : ASSIGN_TO);
|
|
// run Function
|
|
test.run();
|
|
}
|
|
|
|
TEST(MulOp, DDDMatrixMul) {
|
|
LOG(INFO) << "function test for dense = dense * dense matrix";
|
|
for (const auto transa : {false, true}) {
|
|
for (const auto transb : {false, true}) {
|
|
for (const auto dimM : {1, 10, 100}) {
|
|
for (const auto dimN : {1, 10}) {
|
|
for (const auto dimK : {8}) {
|
|
if (transa && transb) {
|
|
continue;
|
|
}
|
|
VLOG(3) << std::setiosflags(std::ios::left) << std::setfill(' ')
|
|
<< " transa=" << transa << " transb=" << transb
|
|
<< " dimM=" << std::setw(5) << dimM
|
|
<< " dimN=" << std::setw(5) << dimN
|
|
<< " dimK=" << std::setw(5) << dimK;
|
|
testFuncDDDMatrix(transa, transb, dimM, dimN, dimK);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* C += A * B, B, C dense, A sparse
|
|
* dense = sparse * dense
|
|
*/
|
|
void testFuncDSparseDMatrix(
|
|
size_t dimM, size_t dimN, size_t dimK, size_t nnz, SparseFormat FORMAT) {
|
|
real scaleT = 1.0;
|
|
// init Test object
|
|
FunctionCompare test("MulOp",
|
|
FuncConfig().set("aTrans", false).set("bTrans", false));
|
|
// prepare input arguments
|
|
/// sparse matrix A : M * K
|
|
test.addInputs(SparseMatrixArg(
|
|
VALUE_TYPE_FLOAT, TensorShape{dimM, dimK}, nnz, FORMAT, FLOAT_VALUE));
|
|
/// matrix B: K * N
|
|
test.addInputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{dimK, dimN}));
|
|
|
|
/// output matrix C: M * N
|
|
test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{dimM, dimN}),
|
|
scaleT == 1.0 ? ADD_TO : ASSIGN_TO);
|
|
// run Function
|
|
test.run();
|
|
}
|
|
|
|
TEST(MuLOp, DSparseDMul) {
|
|
LOG(INFO) << "function test for dense = sparse * dense matrix";
|
|
for (const auto dimM : {10, 100, 1000}) {
|
|
for (const auto dimN : {10, 100}) {
|
|
for (const auto dimK : {3, 10}) {
|
|
for (const auto nnz : {3, 10}) {
|
|
for (const auto FORMAT : {SPARSE_CSR}) {
|
|
VLOG(3) << std::setiosflags(std::ios::left) << std::setfill(' ')
|
|
<< " dimM=" << std::setw(5) << dimM
|
|
<< " dimN=" << std::setw(5) << dimN
|
|
<< " dimK=" << std::setw(5) << dimK
|
|
<< " nnz=" << std::setw(5) << nnz
|
|
<< " format=" << std::setw(5) << FORMAT;
|
|
testFuncDSparseDMatrix(dimM, dimN, dimK, nnz, FORMAT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* C += A * B, A, C dense, B sparse
|
|
* dense = dense * sparse
|
|
*/
|
|
void testFuncDDSparseMatrix(
|
|
size_t dimM, size_t dimN, size_t dimK, size_t nnz, SparseFormat FORMAT) {
|
|
real scaleT = 1.0;
|
|
// init Test object
|
|
FunctionCompare test("MulOp",
|
|
FuncConfig().set("aTrans", false).set("bTrans", false));
|
|
// prepare input arguments
|
|
/// matrix A : M * K
|
|
test.addInputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{dimM, dimK}));
|
|
|
|
/// matrix B: K * N
|
|
test.addInputs(SparseMatrixArg(
|
|
VALUE_TYPE_FLOAT, TensorShape{dimK, dimN}, nnz, FORMAT, FLOAT_VALUE));
|
|
|
|
/// output matrix C: M * N
|
|
test.addOutputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{dimM, dimN}),
|
|
scaleT == 1.0 ? ADD_TO : ASSIGN_TO);
|
|
// run Function
|
|
test.run();
|
|
}
|
|
|
|
TEST(MulOp, DDSparseMul) {
|
|
LOG(INFO) << "function test for dense = dense * sparse matrix";
|
|
for (const auto dimM : {10, 100, 1000}) {
|
|
for (const auto dimN : {10, 100}) {
|
|
for (const auto dimK : {3, 10}) {
|
|
for (const auto nnz : {3, 10}) {
|
|
for (const auto FORMAT : {SPARSE_CSR, SPARSE_CSC}) {
|
|
VLOG(3) << std::setiosflags(std::ios::left) << std::setfill(' ')
|
|
<< " dimM=" << std::setw(5) << dimM
|
|
<< " dimN=" << std::setw(5) << dimN
|
|
<< " dimK=" << std::setw(5) << dimK
|
|
<< " nnz=" << std::setw(5) << nnz
|
|
<< " format=" << std::setw(5) << FORMAT;
|
|
testFuncDDSparseMatrix(dimM, dimN, dimK, nnz, FORMAT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* C += A * B, A sparse, B, C dense
|
|
* sparse = dense * dense
|
|
*/
|
|
void testFuncSparseDDMatrix(
|
|
size_t dimM, size_t dimN, size_t dimK, size_t nnz, SparseFormat FORMAT) {
|
|
real scaleT = 1.0;
|
|
// init Test object
|
|
FunctionCompare test("MulOp",
|
|
FuncConfig().set("aTrans", false).set("bTrans", false));
|
|
// prepare input arguments
|
|
/// matrix A : M * K
|
|
test.addInputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{dimM, dimK}));
|
|
|
|
/// matrix B: K * N
|
|
test.addInputs(BufferArg(VALUE_TYPE_FLOAT, TensorShape{dimK, dimN}));
|
|
|
|
/// output sparse matrix C: M * N
|
|
test.addOutputs(
|
|
SparseMatrixArg(
|
|
VALUE_TYPE_FLOAT, TensorShape{dimM, dimN}, nnz, FORMAT, FLOAT_VALUE),
|
|
scaleT == 1.0 ? ADD_TO : ASSIGN_TO);
|
|
// run Function
|
|
test.run();
|
|
}
|
|
|
|
TEST(MulOp, SparseDDMul) {
|
|
LOG(INFO) << "function test for sparse = dense * dense matrix";
|
|
for (const auto dimM : {10, 100, 1000}) {
|
|
for (const auto dimN : {10, 100}) {
|
|
for (const auto dimK : {3, 10}) {
|
|
for (const auto nnz : {3, 10}) {
|
|
for (const auto FORMAT : {SPARSE_CSC, SPARSE_CSR}) {
|
|
VLOG(3) << std::setiosflags(std::ios::left) << std::setfill(' ')
|
|
<< " dimM=" << std::setw(5) << dimM
|
|
<< " dimN=" << std::setw(5) << dimN
|
|
<< " dimK=" << std::setw(5) << dimK
|
|
<< " nnz=" << std::setw(5) << nnz
|
|
<< " format=" << std::setw(5) << FORMAT;
|
|
testFuncSparseDDMatrix(dimM, dimN, dimK, nnz, FORMAT);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|