parent
b1f09f2788
commit
936301f157
@ -0,0 +1,60 @@
|
||||
/* 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 "MulOp.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
/**
|
||||
* mul operator
|
||||
* out = scaleT * out + scaleAB*(in1 * in2)
|
||||
*
|
||||
* \param outputs[0] output matrix, N * M
|
||||
* \param inputs[0] first input (sparse) matrix, N * K
|
||||
* \param inputs[1] second input matrix, K * M (non-transpose)
|
||||
*/
|
||||
template <DeviceType Device>
|
||||
class MulFunc : public FunctionBase {
|
||||
public:
|
||||
void init(const FuncConfig& config) override {
|
||||
scaleAB_ = config.get<real>("scaleAB");
|
||||
scaleT_ = config.get<real>("scaleT");
|
||||
}
|
||||
|
||||
void calc(const BufferArgs& inputs, const BufferArgs& outputs) override {
|
||||
/// todo(tianbing), add more checks
|
||||
CHECK_EQ((size_t)1, inputs.size());
|
||||
CHECK_EQ((size_t)2, outputs.size());
|
||||
CHECK(inputs[0].data() && inputs[1].data() && outputs[0].data());
|
||||
CHECK_EQ(inputs[0].shape().ndims(), (size_t)2);
|
||||
CHECK_EQ(inputs[1].shape().ndims(), (size_t)2);
|
||||
CHECK_EQ(outputs[0].shape().ndims(), (size_t)2);
|
||||
CHECK_EQ(outputs[0].getArgType(), ASSIGN_TO);
|
||||
|
||||
CHECK(inputs[0].isSparse()) << "SparseMatrix requried here";
|
||||
const auto in1_mat = inputs[0].sparse().SparseMatrix<Device>();
|
||||
auto out_mat = outputs[0].matrix<Device>();
|
||||
const auto in2_mat = inputs[1].matrix<Device>();
|
||||
MulOp<Device>(out_mat, in1_mat, in2_mat, scaleAB_, scaleT_);
|
||||
}
|
||||
|
||||
private:
|
||||
real scaleAB_;
|
||||
real scaleT_;
|
||||
};
|
||||
|
||||
#ifndef PADDLE_ONLY_CPU
|
||||
REGISTER_TYPED_FUNC(MulOp, GPU, MulFunc);
|
||||
#endif
|
||||
} // namespace paddle
|
@ -0,0 +1,30 @@
|
||||
/* 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. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Function.h"
|
||||
#include "paddle/math/Matrix.h"
|
||||
#include "paddle/math/SparseMatrix.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
template <DeviceType DType>
|
||||
void MulOp(GpuMatrix& out,
|
||||
const GpuSparseMatrix& a,
|
||||
const GpuMatrix& b,
|
||||
real scaleAB,
|
||||
real scaleT);
|
||||
|
||||
} // namespace paddle
|
@ -0,0 +1,57 @@
|
||||
/* 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 "hl_base.h"
|
||||
#include "MulOp.h"
|
||||
#include "paddle/math/Matrix.h"
|
||||
#include "paddle/math/SparseMatrix.h"
|
||||
|
||||
namespace paddle {
|
||||
/**
|
||||
* out = scale_t * out + scale_ab * (a * b)
|
||||
*/
|
||||
template <>
|
||||
void MulOp<DEVICE_TYPE_GPU>(GpuMatrix& out,
|
||||
const GpuSparseMatrix& a,
|
||||
const GpuMatrix& b,
|
||||
real scale_ab,
|
||||
real scale_t) {
|
||||
CHECK(out.isContiguous());
|
||||
CHECK(b.isContiguous());
|
||||
CHECK(b.useGpu_ == true) << "Matrix type are not equal";
|
||||
CHECK(!out.trans_ && !b.trans_) << "not supported";
|
||||
if (!a.trans_) {
|
||||
CHECK(out.width_ == b.width_ && out.height_ == a.height_
|
||||
&& a.width_ == b.height_) << "Matrix dimensions are not equal";
|
||||
} else {
|
||||
CHECK(out.width_ == b.width_ && out.height_ == a.width_
|
||||
&& a.height_ == b.height_) << "Matrix dimensions are not equal";
|
||||
}
|
||||
hl_trans_op_t a_trans = a.trans_ ? HPPL_OP_T : HPPL_OP_N;
|
||||
hl_sparse_matrix_s a_data = a.sMatrix_.get();
|
||||
real* b_data = b.data_;
|
||||
real* out_data = out.data_;
|
||||
hl_matrix_csr_mul_dense(a_data,
|
||||
a_trans,
|
||||
b_data,
|
||||
HPPL_OP_N,
|
||||
out_data,
|
||||
out.height_,
|
||||
out.width_,
|
||||
b.height_,
|
||||
scale_ab,
|
||||
scale_t);
|
||||
}
|
||||
|
||||
} // namespace paddle
|
@ -0,0 +1,56 @@
|
||||
/* 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/testing/TestUtil.h"
|
||||
|
||||
using namespace paddle; // NOLINT
|
||||
|
||||
void testSpMatrixMul(int M, int N, int K, real rate, real scale1, real scale2) {
|
||||
/// todo(tianbing) check CPU/GPU
|
||||
const auto gpuFunc = FunctionBase::funcRegistrar_.createByType("MulOP-GPU");
|
||||
gpuFunc->init(FuncConfig().set("scaleAB", scale1).set("scaleT", scale2));
|
||||
|
||||
int nnz = M * K * rate;
|
||||
auto gpuA = std::make_shared<GpuSparseMatrix>(M, K, nnz);
|
||||
const auto gpuB = std::make_shared<GpuMatrix>(K, N);
|
||||
const auto gpuOut = std::make_shared<GpuMatrix>(M, N);
|
||||
|
||||
gpuA->randomizeUniform();
|
||||
gpuB->randomizeUniform();
|
||||
gpuOut->randomizeUniform();
|
||||
|
||||
BufferArgs inputs;
|
||||
BufferArgs outputs;
|
||||
inputs.addArg(*gpuA);
|
||||
inputs.addArg(*gpuB);
|
||||
outputs.addArg(*gpuOut);
|
||||
|
||||
gpuFunc->calc(inputs, outputs);
|
||||
}
|
||||
|
||||
TEST(SMatrix, sMatrixMul) {
|
||||
for (auto M : {1, 40, 128, 200}) {
|
||||
for (auto N : {100, 2000, 20480}) {
|
||||
for (auto K : {100, 512, 1024}) {
|
||||
/// todo(tianbing), add scaleAB and scaleT
|
||||
VLOG(3) << " M=" << M << " N=" << N << " K=" << K;
|
||||
testSpMatrixMul(M, N, K, 0.05, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue