forked from mindspore-Ecosystem/mindspore
Support FP32 Matrix-Vector Multiplication
This commit is contained in:
parent
9593e82e56
commit
cccaab4fdc
|
@ -39,6 +39,7 @@ if (PLATFORM_ARM64)
|
|||
# assembly
|
||||
file(GLOB ASSEMBLY_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../nnacl/assembly/arm64/MatmulFp32Opt.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../nnacl/assembly/arm64/MatVecMulFp32.S
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../nnacl/assembly/arm64/MatmulFp32.S)
|
||||
set_property(SOURCE ${ASSEMBLY_SRC} PROPERTY LANGUAGE C)
|
||||
set(KERNEL_SRC ${KERNEL_SRC} ${ASSEMBLY_SRC})
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
#ifdef __aarch64__
|
||||
.text
|
||||
.align 5
|
||||
.global MatVecMulFp32Neon64
|
||||
#ifndef __APPLE__
|
||||
.type MatVecMulFp32Neon64, %function
|
||||
#endif
|
||||
|
||||
// void MatVecMulFp32Neon64(const float *a, const float *b, float *c, const float *bias, int act_type, int depth, int col)
|
||||
// x0: a
|
||||
// x1: b
|
||||
// x2: c
|
||||
// x3: bias
|
||||
// w4: act_type
|
||||
// w5: depth
|
||||
// w6: col
|
||||
|
||||
MatVecMulFp32Neon64:
|
||||
sub sp, sp, #128
|
||||
st1 {v8.8h, v9.8h, v10.8h, v11.8h}, [sp], #64
|
||||
st1 {v12.8h, v13.8h, v14.8h, v15.8h}, [sp], #64
|
||||
|
||||
mov w14, #4 // sizeof(float)
|
||||
mul w8, w14, w5 // rhs depthx1 block stride
|
||||
mov w14, #4
|
||||
mul w13, w8, w14 // rhs depthx4 block stride
|
||||
|
||||
Loop:
|
||||
mov x15, x0 // reload a ptr
|
||||
mov x7, x1 // reload b ptr
|
||||
mov w9, w5 // reload depth
|
||||
cmp w6, #4
|
||||
blt Loop1x1
|
||||
|
||||
Loop1x4:
|
||||
dup v10.8h, wzr
|
||||
dup v11.8h, wzr
|
||||
dup v12.8h, wzr
|
||||
dup v13.8h, wzr
|
||||
dup v14.8h, wzr
|
||||
|
||||
add x10, x7, x8
|
||||
add x11, x10, x8
|
||||
add x12, x11, x8
|
||||
|
||||
Depth8_1x4:
|
||||
cmp w9, #8
|
||||
blt Depth4_1x4
|
||||
|
||||
ld1 {v0.4s, v1.4s}, [x15], #32
|
||||
ld1 {v2.4s, v3.4s}, [x7], #32
|
||||
ld1 {v4.4s, v5.4s}, [x10], #32
|
||||
fmla v10.4s, v0.4s, v2.4s
|
||||
fmla v10.4s, v1.4s, v3.4s
|
||||
fmla v11.4s, v0.4s, v4.4s
|
||||
fmla v11.4s, v1.4s, v5.4s
|
||||
ld1 {v6.4s, v7.4s}, [x11], #32
|
||||
ld1 {v8.4s, v9.4s}, [x12], #32
|
||||
fmla v12.4s, v0.4s, v6.4s
|
||||
fmla v12.4s, v1.4s, v7.4s
|
||||
fmla v13.4s, v0.4s, v8.4s
|
||||
fmla v13.4s, v1.4s, v9.4s
|
||||
sub w9, w9, #8
|
||||
cbz w9, End1x4
|
||||
b Depth8_1x4
|
||||
|
||||
Depth4_1x4:
|
||||
cmp w9, #4
|
||||
blt Depth1_1x4
|
||||
|
||||
ld1 {v0.4s}, [x15], #16
|
||||
ld1 {v1.4s}, [x7], #16
|
||||
ld1 {v2.4s}, [x10], #16
|
||||
ld1 {v3.4s}, [x11], #16
|
||||
ld1 {v4.4s}, [x12], #16
|
||||
fmla v10.4s, v1.4s, v0.4s
|
||||
fmla v11.4s, v2.4s, v0.4s
|
||||
fmla v12.4s, v3.4s, v0.4s
|
||||
fmla v13.4s, v4.4s, v0.4s
|
||||
sub w9, w9, #4
|
||||
cbz w9, End1x4
|
||||
b Depth8_1x4
|
||||
|
||||
Depth1_1x4:
|
||||
ld1 {v0.s}[0], [x15], #4
|
||||
ld1 {v1.s}[0], [x7], #4
|
||||
ld1 {v1.s}[1], [x10], #4
|
||||
ld1 {v1.s}[2], [x11], #4
|
||||
ld1 {v1.s}[3], [x12], #4
|
||||
|
||||
fmla v14.4s, v1.4s, v0.s[0]
|
||||
sub w9, w9, #1
|
||||
cbz w9, End1x4
|
||||
b Depth1_1x4
|
||||
|
||||
End1x4:
|
||||
faddp v15.4s, v10.4s, v11.4s
|
||||
faddp v16.4s, v12.4s, v13.4s
|
||||
faddp v17.4s, v15.4s, v16.4s
|
||||
fadd v14.4s, v14.4s, v17.4s
|
||||
|
||||
cbz x3, Act1x4
|
||||
ld1 {v15.4s}, [x3], #16
|
||||
fadd v14.4s, v14.4s, v15.4s // add bias
|
||||
|
||||
Act1x4:
|
||||
cmp w4, #3
|
||||
beq Relu6_1x4
|
||||
cmp w4, #1
|
||||
beq Relu1x4
|
||||
b Write1x4
|
||||
|
||||
Relu6_1x4:
|
||||
movi v15.4s, #0x46, lsl #8
|
||||
fmin v14.4s, v14.4s, v15.4s
|
||||
|
||||
Relu1x4:
|
||||
dup v15.4s, wzr
|
||||
fmax v14.4s, v14.4s, v15.4s
|
||||
|
||||
Write1x4:
|
||||
st1 {v14.4s}, [x2], #16
|
||||
sub w6, w6, #4
|
||||
cbz w6, End
|
||||
add x1, x1, x13
|
||||
b Loop
|
||||
|
||||
|
||||
Loop1x1:
|
||||
dup v4.4s, wzr
|
||||
dup v5.4s, wzr
|
||||
|
||||
Depth8_1x1:
|
||||
cmp w9, #8
|
||||
blt Depth4_1x1
|
||||
|
||||
ld1 {v0.4s, v1.4s}, [x15], #32
|
||||
ld1 {v2.4s, v3.4s}, [x7], #32
|
||||
|
||||
fmla v4.4s, v2.4s, v0.4s
|
||||
fmla v4.4s, v3.4s, v1.4s
|
||||
sub w9, w9, #8
|
||||
cbz w9, End1x1
|
||||
b Depth8_1x1
|
||||
|
||||
Depth4_1x1:
|
||||
cmp w9, #4
|
||||
blt Depth1_1x1
|
||||
|
||||
ld1 {v0.4s}, [x15], #16
|
||||
ld1 {v1.4s}, [x7], #16
|
||||
|
||||
fmla v4.4s, v1.4s, v0.4s
|
||||
sub w9, w9, #4
|
||||
cbz w9, End1x1
|
||||
b Depth8_1x1
|
||||
|
||||
Depth1_1x1:
|
||||
ld1 {v0.s}[0], [x15], #4
|
||||
ld1 {v1.s}[0], [x7], #4
|
||||
|
||||
fmla v5.4s, v1.4s, v0.s[0]
|
||||
sub w9, w9, #1
|
||||
cbz w9, End1x1
|
||||
b Depth1_1x1
|
||||
|
||||
End1x1:
|
||||
faddp v6.4s, v4.4s, v4.4s
|
||||
faddp v7.4s, v6.4s, v6.4s
|
||||
fadd v7.4s, v7.4s, v5.4s
|
||||
|
||||
cbz x3, Act1x1
|
||||
ld1 {v8.s}[0], [x3], #4
|
||||
fadd v7.4s, v7.4s, v8.4s // add bias
|
||||
|
||||
Act1x1:
|
||||
cmp w4, #3
|
||||
beq Relu6_1x1
|
||||
cmp w4, #1
|
||||
beq Relu1x1
|
||||
b Write1x1
|
||||
|
||||
Relu6_1x1:
|
||||
movi v8.4s, #0x46, lsl #8
|
||||
fmin v7.4s, v7.4s, v8.4s
|
||||
|
||||
Relu1x1:
|
||||
dup v8.4s, wzr
|
||||
fmax v7.4s, v7.4s, v8.4s
|
||||
|
||||
Write1x1:
|
||||
st1 {v7.s}[0], [x2], #4
|
||||
sub w6, w6, #1
|
||||
cbz w6, End
|
||||
add x1, x1, x8
|
||||
b Loop
|
||||
|
||||
End:
|
||||
sub sp, sp, #128
|
||||
ld1 {v8.8h, v9.8h, v10.8h, v11.8h}, [sp], #64
|
||||
ld1 {v12.8h, v13.8h, v14.8h, v15.8h}, [sp], #64
|
||||
ret
|
||||
#endif
|
|
@ -1,12 +1,12 @@
|
|||
#ifdef __aarch64__
|
||||
.text
|
||||
.align 5
|
||||
.global MatmulFp16Neon64_1xN
|
||||
.global MatVecMulFp16Neon64
|
||||
#ifndef __APPLE__
|
||||
.type MatmulFp16Neon64_1xN, %function
|
||||
.type MatVecMulFp16Neon64, %function
|
||||
#endif
|
||||
|
||||
// void MatmulFp16Neon64_1xN(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, int act_type, int depth, int col)
|
||||
// void MatVecMulFp16Neon64(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, int act_type, int depth, int col)
|
||||
// x0: a
|
||||
// x1: b
|
||||
// x2: c
|
||||
|
@ -15,7 +15,7 @@
|
|||
// w5: depth
|
||||
// w6: col
|
||||
|
||||
MatmulFp16Neon64_1xN:
|
||||
MatVecMulFp16Neon64:
|
||||
sub sp, sp, #128
|
||||
st1 {v8.8h, v9.8h, v10.8h, v11.8h}, [sp], #64
|
||||
st1 {v12.8h, v13.8h, v14.8h, v15.8h}, [sp], #64
|
|
@ -289,9 +289,9 @@ void MatMulFp16(const float16_t *a, const float16_t *b, float16_t *c, const floa
|
|||
return;
|
||||
}
|
||||
|
||||
void MatVecMulFp16(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, int act_type, int depth,
|
||||
int col) {
|
||||
MatmulFp16Neon64_1xN(a, b, c, bias, act_type, depth, col);
|
||||
void MatVecMulFp16(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, ActType act_type,
|
||||
int depth, int col) {
|
||||
MatVecMulFp16Neon64(a, b, c, bias, (int)act_type, depth, col);
|
||||
}
|
||||
|
||||
void RowMajor2Col16MajorFp16Opt(float16_t *src_ptr, float16_t *dst_ptr, size_t row, size_t col) {
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
#ifndef MINDSPORE_LITE_NNACL_FP16_MATMUL_H_
|
||||
#define MINDSPORE_LITE_NNACL_FP16_MATMUL_H_
|
||||
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#ifdef ENABLE_NEON
|
||||
#include <arm_neon.h>
|
||||
#endif
|
||||
#include "nnacl/errorcode.h"
|
||||
#include "nnacl/op_base.h"
|
||||
#include "nnacl/matmul_parameter.h"
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -35,8 +35,8 @@ void MatMul16x8(const float16_t *a, const float16_t *b, float16_t *dst, const fl
|
|||
void MatMulFp16(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, ActType act_type,
|
||||
int depth, int row, int col, int stride, int out_type);
|
||||
|
||||
void MatVecMulFp16(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, int act_type, int depth,
|
||||
int col);
|
||||
void MatVecMulFp16(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, ActType act_type,
|
||||
int depth, int col);
|
||||
|
||||
void ColMajor2Row8MajorFp16(void *src_ptr, float16_t *dst_ptr, size_t row, size_t col, bool src_float16);
|
||||
|
||||
|
@ -48,8 +48,8 @@ void MatmulFp16Neon64(const float16_t *a, const float16_t *b, float16_t *c, cons
|
|||
void MatmulFp16Neon64Opt(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, int act_type,
|
||||
size_t depth, size_t row, size_t col, size_t stride, size_t write_nhwc);
|
||||
|
||||
void MatmulFp16Neon64_1xN(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, int act_type,
|
||||
int depth, int col);
|
||||
void MatVecMulFp16Neon64(const float16_t *a, const float16_t *b, float16_t *c, const float16_t *bias, int act_type,
|
||||
int depth, int col);
|
||||
|
||||
void RowMajor2Col16MajorFp16(void *src, float16_t *dst, int row, int col, bool is_fp32_src);
|
||||
|
||||
|
|
|
@ -16,6 +16,14 @@
|
|||
|
||||
#include "nnacl/fp32/matmul.h"
|
||||
|
||||
void RowMajor2ColMajor(float *src_ptr, float *dst_ptr, int row, int col) {
|
||||
for (int r = 0; r < row; ++r) {
|
||||
for (int c = 0; c < col; ++c) {
|
||||
dst_ptr[c * row + r] = src_ptr[r * col + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RowMajor2Row4Major(float *src_ptr, float *dst_ptr, int row, int col) {
|
||||
for (int r = 0; r < row; r++) {
|
||||
float *src = src_ptr + r * col;
|
||||
|
@ -562,6 +570,12 @@ void MatMulOpt(const float *a, const float *b, float *c, const float *bias, ActT
|
|||
#endif
|
||||
}
|
||||
|
||||
void MatVecMul(const float *a, const float *b, float *c, const float *bias, ActType act_type, int depth, int col) {
|
||||
#ifdef ENABLE_ARM64
|
||||
MatVecMulFp32Neon64(a, b, c, bias, (int)act_type, depth, col);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NNACL_INFER_SHAPE
|
||||
static void SwapDims(int *dims, int index1, int index2) {
|
||||
int tmp = dims[index1];
|
||||
|
|
|
@ -17,17 +17,19 @@
|
|||
#ifndef MINDSPORE_LITE_NNACL_FP32_MATMUL_H_
|
||||
#define MINDSPORE_LITE_NNACL_FP32_MATMUL_H_
|
||||
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include "nnacl/errorcode.h"
|
||||
#include "nnacl/op_base.h"
|
||||
#include "nnacl/matmul_parameter.h"
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void MatMulOpt(const float *a, const float *b, float *c, const float *bias, ActType act_type, int deep, int row,
|
||||
int col, size_t stride, int out_type);
|
||||
void MatVecMul(const float *a, const float *b, float *c, const float *bias, ActType act_type, int depth, int col);
|
||||
void RowMajor2ColMajor(float *src_ptr, float *dst_ptr, int row, int col);
|
||||
void RowMajor2Row4Major(float *src_ptr, float *dst_ptr, int row, int col);
|
||||
void RowMajor2Row8Major(float *src_ptr, float *dst_ptr, int row, int col);
|
||||
void RowMajor2Row12Major(float *src_ptr, float *dst_ptr, int row, int col);
|
||||
|
@ -39,6 +41,7 @@ void MatmulFloatNeon64(const float *a, const float *b, float *c, const float *bi
|
|||
int col, size_t stride, size_t writeNhwc, size_t WriteWino);
|
||||
void MatmulFloatNeon64Opt(const float *a, const float *b, float *c, const float *bias, int act_type, int depth, int row,
|
||||
int col, size_t stride, size_t write_mode);
|
||||
void MatVecMulFp32Neon64(const float *a, const float *b, float *c, const float *bias, int act_type, int depth, int col);
|
||||
#elif ENABLE_ARM32
|
||||
void MatmulFloatNeon32(const float *a, const float *b, float *c, const float *bias, int act_type, int depth, int row,
|
||||
int col, int stride, size_t writeNhwc, size_t WriteWino);
|
||||
|
|
|
@ -27,13 +27,13 @@ FullconnectionCPUKernel::~FullconnectionCPUKernel() {
|
|||
}
|
||||
|
||||
void FullconnectionCPUKernel::FreeBuf() {
|
||||
if (a_c12_ptr_ != nullptr) {
|
||||
free(a_c12_ptr_);
|
||||
a_c12_ptr_ = nullptr;
|
||||
if (a_pack_ptr_ != nullptr) {
|
||||
free(a_pack_ptr_);
|
||||
a_pack_ptr_ = nullptr;
|
||||
}
|
||||
if (b_r8_ptr_ != nullptr) {
|
||||
free(b_r8_ptr_);
|
||||
b_r8_ptr_ = nullptr;
|
||||
if (b_pack_ptr_ != nullptr) {
|
||||
free(b_pack_ptr_);
|
||||
b_pack_ptr_ = nullptr;
|
||||
}
|
||||
if (bias_ptr_ != nullptr) {
|
||||
free(bias_ptr_);
|
||||
|
@ -56,37 +56,50 @@ int FullconnectionCPUKernel::ReSize() {
|
|||
thread_count_ = MSMIN(thread_count_, UP_DIV(fc_param_->col_8_, 8));
|
||||
thread_stride_ = UP_DIV(UP_DIV(fc_param_->col_8_, 8), thread_count_);
|
||||
|
||||
bias_ptr_ = reinterpret_cast<float *>(malloc(fc_param_->col_8_ * sizeof(float)));
|
||||
memset(bias_ptr_, 0, fc_param_->col_8_ * sizeof(float));
|
||||
#ifdef ENABLE_ARM64
|
||||
if (fc_param_->row_ == 1) {
|
||||
is_vector_input_ = true;
|
||||
}
|
||||
#endif
|
||||
if (in_tensors_.size() == 3) {
|
||||
int col_tmp = is_vector_input_ ? fc_param_->col_ : fc_param_->col_8_;
|
||||
bias_ptr_ = reinterpret_cast<float *>(malloc(col_tmp * sizeof(float)));
|
||||
memcpy(bias_ptr_, in_tensors_[2]->MutableData(), fc_param_->col_ * sizeof(float));
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ARM32
|
||||
a_c12_ptr_ = reinterpret_cast<float *>(malloc(fc_param_->row_4_ * fc_param_->deep_ * sizeof(float)));
|
||||
if (a_c12_ptr_ == nullptr) {
|
||||
a_pack_ptr_ = reinterpret_cast<float *>(malloc(fc_param_->row_4_ * fc_param_->deep_ * sizeof(float)));
|
||||
if (a_pack_ptr_ == nullptr) {
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memset(a_c12_ptr_, 0, fc_param_->row_4_ * fc_param_->deep_ * sizeof(float));
|
||||
memset(a_pack_ptr_, 0, fc_param_->row_4_ * fc_param_->deep_ * sizeof(float));
|
||||
#else
|
||||
a_c12_ptr_ = reinterpret_cast<float *>(malloc(fc_param_->row_12_ * fc_param_->deep_ * sizeof(float)));
|
||||
if (a_c12_ptr_ == nullptr) {
|
||||
int row_tmp = is_vector_input_ ? 1 : fc_param_->row_12_;
|
||||
a_pack_ptr_ = reinterpret_cast<float *>(malloc(row_tmp * fc_param_->deep_ * sizeof(float)));
|
||||
if (a_pack_ptr_ == nullptr) {
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memset(a_c12_ptr_, 0, fc_param_->row_12_ * fc_param_->deep_ * sizeof(float));
|
||||
memset(a_pack_ptr_, 0, row_tmp * fc_param_->deep_ * sizeof(float));
|
||||
#endif
|
||||
|
||||
b_r8_ptr_ = reinterpret_cast<float *>(malloc(fc_param_->col_8_ * fc_param_->deep_ * sizeof(float)));
|
||||
if (b_r8_ptr_ == nullptr) {
|
||||
int col_tmp = is_vector_input_ ? fc_param_->col_ : fc_param_->col_8_;
|
||||
b_pack_ptr_ = reinterpret_cast<float *>(malloc(col_tmp * fc_param_->deep_ * sizeof(float)));
|
||||
if (b_pack_ptr_ == nullptr) {
|
||||
FreeBuf();
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memset(b_r8_ptr_, 0, fc_param_->col_8_ * fc_param_->deep_ * sizeof(float));
|
||||
memset(b_pack_ptr_, 0, col_tmp * fc_param_->deep_ * sizeof(float));
|
||||
|
||||
fc_param_->a_const_ = (in_tensors_[0]->data_c() != nullptr);
|
||||
fc_param_->b_const_ = (in_tensors_[1]->data_c() != nullptr);
|
||||
if (fc_param_->a_const_) InitMatrixA(reinterpret_cast<float *>(in_tensors_[0]->MutableData()), a_c12_ptr_);
|
||||
if (fc_param_->b_const_) InitMatrixB(reinterpret_cast<float *>(in_tensors_[1]->MutableData()), b_r8_ptr_);
|
||||
if (fc_param_->a_const_) {
|
||||
InitMatrixA(reinterpret_cast<float *>(in_tensors_[0]->MutableData()), a_pack_ptr_);
|
||||
a_ptr_ = a_pack_ptr_;
|
||||
}
|
||||
if (fc_param_->b_const_) {
|
||||
InitMatrixB(reinterpret_cast<float *>(in_tensors_[1]->MutableData()), b_pack_ptr_);
|
||||
b_ptr_ = b_pack_ptr_;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -98,14 +111,24 @@ int FullconnectionCPUKernel::Init() {
|
|||
}
|
||||
|
||||
void FullconnectionCPUKernel::InitMatrixA(float *src_ptr, float *dst_ptr) {
|
||||
if (is_vector_input_) {
|
||||
memcpy(dst_ptr, src_ptr, fc_param_->deep_ * sizeof(float));
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ARM32
|
||||
RowMajor2Col4Major(src_ptr, a_c12_ptr_, fc_param_->row_, fc_param_->deep_);
|
||||
RowMajor2Col4Major(src_ptr, a_pack_ptr_, fc_param_->row_, fc_param_->deep_);
|
||||
#else
|
||||
RowMajor2Col12Major(src_ptr, a_c12_ptr_, fc_param_->row_, fc_param_->deep_);
|
||||
RowMajor2Col12Major(src_ptr, a_pack_ptr_, fc_param_->row_, fc_param_->deep_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FullconnectionCPUKernel::InitMatrixB(float *src_ptr, float *dst_ptr) {
|
||||
if (is_vector_input_) {
|
||||
memcpy(dst_ptr, src_ptr, fc_param_->col_ * fc_param_->deep_ * sizeof(float));
|
||||
return;
|
||||
}
|
||||
|
||||
RowMajor2Col8Major(src_ptr, dst_ptr, fc_param_->col_, fc_param_->deep_);
|
||||
}
|
||||
|
||||
|
@ -125,9 +148,16 @@ int FullconnectionCPUKernel::DoMatmul(int task_id) {
|
|||
return RET_OK;
|
||||
}
|
||||
|
||||
MatMulOpt(a_c12_ptr_, b_r8_ptr_ + task_id * thread_stride_ * C8NUM * fc_param_->deep_,
|
||||
c_r_ptr + task_id * thread_stride_ * C8NUM, bias_ptr_ + task_id * thread_stride_ * C8NUM,
|
||||
fc_param_->act_type_, fc_param_->deep_, fc_param_->row_, cur_oc, fc_param_->col_, OutType_Nhwc);
|
||||
auto b = b_ptr_ + task_id * thread_stride_ * C8NUM * fc_param_->deep_;
|
||||
auto bias = (bias_ptr_ == nullptr) ? nullptr : bias_ptr_ + task_id * thread_stride_ * C8NUM;
|
||||
auto c = c_ptr_ + task_id * thread_stride_ * C8NUM;
|
||||
if (is_vector_input_) {
|
||||
MatVecMul(a_ptr_, b, c, bias, fc_param_->act_type_, fc_param_->deep_, cur_oc);
|
||||
} else {
|
||||
MatMulOpt(a_ptr_, b, c, bias, fc_param_->act_type_, fc_param_->deep_, fc_param_->row_, cur_oc, fc_param_->col_,
|
||||
OutType_Nhwc);
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -139,11 +169,24 @@ int FullconnectionCPUKernel::Run() {
|
|||
}
|
||||
auto a_ptr = reinterpret_cast<float *>(in_tensors_.at(0)->data_c());
|
||||
auto b_ptr = reinterpret_cast<float *>(in_tensors_.at(1)->data_c());
|
||||
c_r_ptr = reinterpret_cast<float *>(out_tensors_.at(0)->data_c());
|
||||
|
||||
if (!fc_param_->a_const_) InitMatrixA(a_ptr, a_c12_ptr_);
|
||||
if (!fc_param_->b_const_) InitMatrixB(b_ptr, b_r8_ptr_);
|
||||
c_ptr_ = reinterpret_cast<float *>(out_tensors_.at(0)->data_c());
|
||||
|
||||
if (!fc_param_->a_const_) {
|
||||
if (is_vector_input_) {
|
||||
a_ptr_ = a_ptr;
|
||||
} else {
|
||||
InitMatrixA(a_ptr, a_pack_ptr_);
|
||||
a_ptr_ = a_pack_ptr_;
|
||||
}
|
||||
}
|
||||
if (!fc_param_->b_const_) {
|
||||
if (is_vector_input_) {
|
||||
b_ptr_ = b_ptr;
|
||||
} else {
|
||||
InitMatrixB(b_ptr, b_pack_ptr_);
|
||||
b_ptr_ = b_pack_ptr_;
|
||||
}
|
||||
}
|
||||
ParallelLaunch(this->context_->thread_pool_, FcFp32MatmulRun, this, thread_count_);
|
||||
|
||||
return RET_OK;
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include <vector>
|
||||
#include "src/runtime/kernel/arm/base/fullconnection_base.h"
|
||||
#include "include/errorcode.h"
|
||||
#include "include/context.h"
|
||||
#include "include/errorcode.h"
|
||||
#include "nnacl/fp32/matmul.h"
|
||||
|
||||
using mindspore::lite::InnerContext;
|
||||
|
@ -47,10 +47,13 @@ class FullconnectionCPUKernel : public FullconnectionBaseCPUKernel {
|
|||
void InitMatrixB(float *src_ptr, float *dst_ptr);
|
||||
|
||||
private:
|
||||
float *a_c12_ptr_ = nullptr;
|
||||
float *b_r8_ptr_ = nullptr;
|
||||
float *c_r_ptr = nullptr;
|
||||
float *a_pack_ptr_ = nullptr;
|
||||
float *b_pack_ptr_ = nullptr;
|
||||
float *c_ptr_ = nullptr;
|
||||
float *bias_ptr_ = nullptr;
|
||||
float *a_ptr_ = nullptr;
|
||||
float *b_ptr_ = nullptr;
|
||||
bool is_vector_input_ = false;
|
||||
};
|
||||
} // namespace mindspore::kernel
|
||||
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_FULLCONNECTION_H_
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
*/
|
||||
|
||||
#include "src/runtime/kernel/arm/fp32/matmul.h"
|
||||
#include "include/errorcode.h"
|
||||
#include "nnacl/fp32/matmul.h"
|
||||
#include "src/runtime/runtime_api.h"
|
||||
#include "include/errorcode.h"
|
||||
|
||||
using mindspore::lite::RET_ERROR;
|
||||
using mindspore::lite::RET_INPUT_TENSOR_ERROR;
|
||||
|
@ -28,13 +28,13 @@ namespace mindspore::kernel {
|
|||
MatmulCPUKernel::~MatmulCPUKernel() { FreeTmpBuffer(); }
|
||||
|
||||
void MatmulCPUKernel::FreeTmpBuffer() {
|
||||
if (a_c12_ptr_ != nullptr) {
|
||||
free(a_c12_ptr_);
|
||||
a_c12_ptr_ = nullptr;
|
||||
if (a_pack_ptr_ != nullptr) {
|
||||
free(a_pack_ptr_);
|
||||
a_pack_ptr_ = nullptr;
|
||||
}
|
||||
if (b_r8_ptr_ != nullptr) {
|
||||
free(b_r8_ptr_);
|
||||
b_r8_ptr_ = nullptr;
|
||||
if (b_pack_ptr_ != nullptr) {
|
||||
free(b_pack_ptr_);
|
||||
b_pack_ptr_ = nullptr;
|
||||
}
|
||||
if (bias_ptr_ != nullptr) {
|
||||
free(bias_ptr_);
|
||||
|
@ -50,24 +50,30 @@ int MatmulCPUKernel::MallocMatrixABuffer() {
|
|||
}
|
||||
params_->batch = batch;
|
||||
params_->row_ = params_->a_transpose_ ? a_shape[a_shape.size() - 1] : a_shape[a_shape.size() - 2];
|
||||
#ifdef ENABLE_ARM64
|
||||
if (params_->row_ == 1) {
|
||||
is_vector_a_ = true;
|
||||
}
|
||||
#endif
|
||||
params_->deep_ = params_->a_transpose_ ? a_shape[a_shape.size() - 2] : a_shape[a_shape.size() - 1];
|
||||
params_->row_4_ = UP_ROUND(params_->row_, C4NUM);
|
||||
params_->row_12_ = UP_ROUND(params_->row_, C12NUM);
|
||||
|
||||
#ifdef ENABLE_ARM32
|
||||
a_c12_ptr_ = reinterpret_cast<float *>(malloc(params_->batch * params_->row_4_ * params_->deep_ * sizeof(float)));
|
||||
if (a_c12_ptr_ == nullptr) {
|
||||
a_pack_ptr_ = reinterpret_cast<float *>(malloc(params_->batch * params_->row_4_ * params_->deep_ * sizeof(float)));
|
||||
if (a_pack_ptr_ == nullptr) {
|
||||
FreeTmpBuffer();
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memset(a_c12_ptr_, 0, params_->row_4_ * params_->deep_ * sizeof(float));
|
||||
memset(a_pack_ptr_, 0, params_->row_4_ * params_->deep_ * sizeof(float));
|
||||
#else
|
||||
a_c12_ptr_ = reinterpret_cast<float *>(malloc(params_->batch * params_->row_12_ * params_->deep_ * sizeof(float)));
|
||||
if (a_c12_ptr_ == nullptr) {
|
||||
int row_tmp = is_vector_a_ ? 1 : params_->row_12_;
|
||||
a_pack_ptr_ = reinterpret_cast<float *>(malloc(params_->batch * row_tmp * params_->deep_ * sizeof(float)));
|
||||
if (a_pack_ptr_ == nullptr) {
|
||||
FreeTmpBuffer();
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memset(a_c12_ptr_, 0, params_->row_12_ * params_->deep_ * sizeof(float));
|
||||
memset(a_pack_ptr_, 0, params_->batch * row_tmp * params_->deep_ * sizeof(float));
|
||||
#endif
|
||||
return RET_OK;
|
||||
}
|
||||
|
@ -86,12 +92,13 @@ int MatmulCPUKernel::MallocMatrixBBuffer() {
|
|||
params_->col_8_ = UP_ROUND(params_->col_, 8);
|
||||
params_->deep_ = params_->b_transpose_ ? b_shape[b_shape.size() - 1] : b_shape[b_shape.size() - 2];
|
||||
|
||||
b_r8_ptr_ = reinterpret_cast<float *>(malloc(params_->batch * params_->col_8_ * params_->deep_ * sizeof(float)));
|
||||
if (b_r8_ptr_ == nullptr) {
|
||||
int col_tmp = is_vector_a_ ? params_->col_ : params_->col_8_;
|
||||
b_pack_ptr_ = reinterpret_cast<float *>(malloc(params_->batch * col_tmp * params_->deep_ * sizeof(float)));
|
||||
if (b_pack_ptr_ == nullptr) {
|
||||
FreeTmpBuffer();
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memset(b_r8_ptr_, 0, params_->col_8_ * params_->deep_ * sizeof(float));
|
||||
memset(b_pack_ptr_, 0, params_->batch * col_tmp * params_->deep_ * sizeof(float));
|
||||
|
||||
thread_count_ = MSMIN(thread_count_, UP_DIV(params_->col_8_, 8));
|
||||
thread_stride_ = UP_DIV(UP_DIV(params_->col_8_, 8), thread_count_);
|
||||
|
@ -99,24 +106,22 @@ int MatmulCPUKernel::MallocMatrixBBuffer() {
|
|||
}
|
||||
|
||||
int MatmulCPUKernel::InitBias() {
|
||||
auto c_shape = out_tensors_[0]->shape();
|
||||
if (c_shape.empty()) {
|
||||
return RET_OK;
|
||||
}
|
||||
auto col_8 = UP_ROUND(c_shape[c_shape.size() - 1], 8);
|
||||
bias_ptr_ = reinterpret_cast<float *>(malloc(col_8 * sizeof(float)));
|
||||
if (bias_ptr_ == nullptr) {
|
||||
FreeTmpBuffer();
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memset(bias_ptr_, 0, col_8 * sizeof(float));
|
||||
if (in_tensors_.size() == 3) {
|
||||
auto c_shape = out_tensors_[0]->shape();
|
||||
auto bias_shape = in_tensors_[1]->shape();
|
||||
if (bias_shape[bias_shape.size() - 1] != c_shape[c_shape.size() - 1]) {
|
||||
MS_LOG(ERROR) << "The bias'dimension is not equal with colum";
|
||||
FreeTmpBuffer();
|
||||
return RET_INPUT_TENSOR_ERROR;
|
||||
}
|
||||
auto col = c_shape[c_shape.size() - 1];
|
||||
auto col_8 = UP_ROUND(col, 8);
|
||||
auto col_tmp = is_vector_a_ ? col : col_8;
|
||||
bias_ptr_ = reinterpret_cast<float *>(malloc(col_tmp * sizeof(float)));
|
||||
if (bias_ptr_ == nullptr) {
|
||||
FreeTmpBuffer();
|
||||
return RET_MEMORY_FAILED;
|
||||
}
|
||||
memcpy(bias_ptr_, in_tensors_[2]->data_c(), in_tensors_[2]->ElementsNum() * sizeof(float));
|
||||
}
|
||||
return RET_OK;
|
||||
|
@ -124,9 +129,9 @@ int MatmulCPUKernel::InitBias() {
|
|||
|
||||
int MatmulCPUKernel::ReSize() {
|
||||
if (params_->a_const_ == false || params_->a_has_shape_ == false) {
|
||||
if (a_c12_ptr_ != nullptr) {
|
||||
free(a_c12_ptr_);
|
||||
a_c12_ptr_ = nullptr;
|
||||
if (a_pack_ptr_ != nullptr) {
|
||||
free(a_pack_ptr_);
|
||||
a_pack_ptr_ = nullptr;
|
||||
}
|
||||
auto ret = MallocMatrixABuffer();
|
||||
if (ret != RET_OK) {
|
||||
|
@ -135,9 +140,9 @@ int MatmulCPUKernel::ReSize() {
|
|||
}
|
||||
}
|
||||
if (params_->b_const_ == false || params_->b_has_shape_ == false) {
|
||||
if (b_r8_ptr_ != nullptr) {
|
||||
free(b_r8_ptr_);
|
||||
b_r8_ptr_ = nullptr;
|
||||
if (b_pack_ptr_ != nullptr) {
|
||||
free(b_pack_ptr_);
|
||||
b_pack_ptr_ = nullptr;
|
||||
}
|
||||
auto ret = MallocMatrixBBuffer();
|
||||
if (ret != RET_OK) {
|
||||
|
@ -158,6 +163,11 @@ int MatmulCPUKernel::ReSize() {
|
|||
}
|
||||
|
||||
void MatmulCPUKernel::InitMatrixA(float *src_ptr, float *dst_ptr) {
|
||||
if (is_vector_a_) {
|
||||
memcpy(dst_ptr, src_ptr, params_->batch * params_->deep_ * sizeof(float));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < params_->batch; i++) {
|
||||
float *src = src_ptr + i * params_->deep_ * params_->row_;
|
||||
#ifdef ENABLE_ARM32
|
||||
|
@ -180,6 +190,19 @@ void MatmulCPUKernel::InitMatrixA(float *src_ptr, float *dst_ptr) {
|
|||
}
|
||||
|
||||
void MatmulCPUKernel::InitMatrixB(float *src_ptr, float *dst_ptr) {
|
||||
if (is_vector_a_) {
|
||||
if (params_->b_transpose_) {
|
||||
memcpy(dst_ptr, src_ptr, params_->batch * params_->col_ * params_->deep_ * sizeof(float));
|
||||
} else {
|
||||
for (int i = 0; i < params_->batch; i++) {
|
||||
float *src = src_ptr + i * params_->deep_ * params_->col_;
|
||||
float *dst = dst_ptr + i * params_->deep_ * params_->col_;
|
||||
RowMajor2ColMajor(src, dst, params_->deep_, params_->col_);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < params_->batch; i++) {
|
||||
float *src = src_ptr + i * params_->deep_ * params_->col_;
|
||||
float *dst = dst_ptr + i * params_->deep_ * params_->col_8_;
|
||||
|
@ -213,10 +236,12 @@ int MatmulCPUKernel::Init() {
|
|||
params_->a_const_ = (in_tensors_[0]->data_c() != nullptr);
|
||||
params_->b_const_ = (in_tensors_[1]->data_c() != nullptr);
|
||||
if (params_->a_const_ == true) {
|
||||
InitMatrixA(reinterpret_cast<float *>(in_tensors_[0]->data_c()), a_c12_ptr_);
|
||||
InitMatrixA(reinterpret_cast<float *>(in_tensors_[0]->data_c()), a_pack_ptr_);
|
||||
a_ptr_ = a_pack_ptr_;
|
||||
}
|
||||
if (params_->b_const_ == true) {
|
||||
InitMatrixB(reinterpret_cast<float *>(in_tensors_[1]->data_c()), b_r8_ptr_);
|
||||
InitMatrixB(reinterpret_cast<float *>(in_tensors_[1]->data_c()), b_pack_ptr_);
|
||||
b_ptr_ = b_pack_ptr_;
|
||||
}
|
||||
if (!InferShapeDone()) {
|
||||
return RET_OK;
|
||||
|
@ -234,9 +259,14 @@ int MatmulCPUKernel::RunImpl(int task_id) {
|
|||
if (cur_oc <= 0) {
|
||||
return RET_OK;
|
||||
}
|
||||
MatMulOpt(a_ptr_, b_ptr_ + task_id * thread_stride_ * C8NUM * params_->deep_,
|
||||
c_ptr_ + task_id * thread_stride_ * C8NUM, bias_ptr_ + task_id * thread_stride_ * C8NUM, ActType_No,
|
||||
params_->deep_, params_->row_, cur_oc, params_->col_, OutType_Nhwc);
|
||||
auto b = cur_b_ptr_ + task_id * thread_stride_ * C8NUM * params_->deep_;
|
||||
auto c = cur_c_ptr_ + task_id * thread_stride_ * C8NUM;
|
||||
auto bias = bias_ptr_ ? bias_ptr_ + task_id * thread_stride_ * C8NUM : NULL;
|
||||
if (is_vector_a_) {
|
||||
MatVecMul(cur_a_ptr_, b, c, bias, ActType_No, params_->deep_, cur_oc);
|
||||
} else {
|
||||
MatMulOpt(cur_a_ptr_, b, c, bias, ActType_No, params_->deep_, params_->row_, cur_oc, params_->col_, OutType_Nhwc);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -261,16 +291,32 @@ int MatmulCPUKernel::Run() {
|
|||
auto c_src = reinterpret_cast<float *>(out_tensors_[0]->data_c());
|
||||
|
||||
if (params_->a_const_ == false || is_train()) {
|
||||
InitMatrixA(a_src, a_c12_ptr_);
|
||||
if (is_vector_a_) {
|
||||
a_ptr_ = a_src;
|
||||
} else {
|
||||
InitMatrixA(a_src, a_pack_ptr_);
|
||||
a_ptr_ = a_pack_ptr_;
|
||||
}
|
||||
}
|
||||
if (params_->b_const_ == false || is_train()) {
|
||||
InitMatrixB(b_src, b_r8_ptr_);
|
||||
if (is_vector_a_) {
|
||||
b_ptr_ = b_src;
|
||||
} else {
|
||||
InitMatrixB(b_src, b_pack_ptr_);
|
||||
b_ptr_ = b_pack_ptr_;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < params_->batch; ++i) {
|
||||
a_ptr_ = a_c12_ptr_ + i * params_->row_12_ * params_->deep_;
|
||||
b_ptr_ = b_r8_ptr_ + i * params_->deep_ * params_->col_8_;
|
||||
c_ptr_ = c_src + i * params_->row_ * params_->col_;
|
||||
if (is_vector_a_) {
|
||||
cur_a_ptr_ = a_ptr_ + i * params_->deep_;
|
||||
cur_b_ptr_ = b_ptr_ + i * params_->deep_ * params_->col_;
|
||||
cur_c_ptr_ = c_src + i * params_->row_ * params_->col_;
|
||||
} else {
|
||||
cur_a_ptr_ = a_ptr_ + i * params_->row_12_ * params_->deep_;
|
||||
cur_b_ptr_ = b_ptr_ + i * params_->deep_ * params_->col_8_;
|
||||
cur_c_ptr_ = c_src + i * params_->row_ * params_->col_;
|
||||
}
|
||||
ParallelLaunch(this->context_->thread_pool_, MatmulFloatRun, this, thread_count_);
|
||||
}
|
||||
return RET_OK;
|
||||
|
@ -280,10 +326,10 @@ void MatmulCPUKernel::eval() {
|
|||
// Copy weights after training
|
||||
LiteKernel::eval();
|
||||
if (params_->a_const_ == true) {
|
||||
InitMatrixA(reinterpret_cast<float *>(in_tensors_[0]->MutableData()), a_c12_ptr_);
|
||||
InitMatrixA(reinterpret_cast<float *>(in_tensors_[0]->MutableData()), a_pack_ptr_);
|
||||
}
|
||||
if (params_->b_const_ == true) {
|
||||
InitMatrixB(reinterpret_cast<float *>(in_tensors_[1]->MutableData()), b_r8_ptr_);
|
||||
InitMatrixB(reinterpret_cast<float *>(in_tensors_[1]->MutableData()), b_pack_ptr_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_MATMUL_H_
|
||||
|
||||
#include <vector>
|
||||
#include "src/lite_kernel.h"
|
||||
#include "nnacl/matmul_parameter.h"
|
||||
#include "src/lite_kernel.h"
|
||||
#include "src/runtime/kernel/arm/base/matmul_base.h"
|
||||
|
||||
namespace mindspore::kernel {
|
||||
|
@ -45,12 +45,15 @@ class MatmulCPUKernel : public MatmulBaseCPUKernel {
|
|||
void FreeTmpBuffer();
|
||||
|
||||
private:
|
||||
float *a_c12_ptr_ = nullptr;
|
||||
float *b_r8_ptr_ = nullptr;
|
||||
float *a_pack_ptr_ = nullptr;
|
||||
float *b_pack_ptr_ = nullptr;
|
||||
float *bias_ptr_ = nullptr;
|
||||
float *a_ptr_ = nullptr;
|
||||
float *b_ptr_ = nullptr;
|
||||
float *c_ptr_ = nullptr;
|
||||
float *cur_a_ptr_ = nullptr;
|
||||
float *cur_b_ptr_ = nullptr;
|
||||
float *cur_c_ptr_ = nullptr;
|
||||
bool is_vector_a_ = false;
|
||||
};
|
||||
} // namespace mindspore::kernel
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
#include <sys/time.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "common/common_test.h"
|
||||
#include "src/common/file_utils.h"
|
||||
#include "src/runtime/kernel/arm/fp32/fullconnection.h"
|
||||
#include "nnacl/fp32/matmul.h"
|
||||
#include "src/common/file_utils.h"
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "src/runtime/kernel/arm/fp32/fullconnection.h"
|
||||
|
||||
namespace mindspore {
|
||||
using mindspore::lite::Tensor;
|
||||
|
@ -144,4 +144,59 @@ TEST_F(TestFcFp32, FcTest2) {
|
|||
fc->Run();
|
||||
CompareOutputData(reinterpret_cast<float *>(outputs_[0]->MutableData()), correct, total_size, 0.0001);
|
||||
}
|
||||
|
||||
int FcTestInit3(std::vector<lite::Tensor *> *inputs_, std::vector<lite::Tensor *> *outputs_,
|
||||
MatMulParameter *matmal_param, float **correct) {
|
||||
Tensor *in_t = new Tensor(kNumberTypeFloat, {1, 1, 1, 20}, schema::Format_NHWC, lite::Tensor::Category::CONST);
|
||||
in_t->MallocData();
|
||||
float in[] = {1, 0, 3, 0, 4, 5, 2, 5, 2, 5, 1, 5, 0, 1, 2, 0, 2, 1, 0, 5};
|
||||
memcpy(in_t->MutableData(), in, sizeof(float) * in_t->ElementsNum());
|
||||
inputs_->push_back(in_t);
|
||||
|
||||
Tensor *weight_t = new Tensor(kNumberTypeFloat, {16, 20}, schema::Format_NHWC, lite::Tensor::Category::CONST);
|
||||
weight_t->MallocData();
|
||||
float weight[] = {0, 5, 5, 3, 0, 5, 3, 1, 0, 1, 3, 0, 5, 5, 2, 4, 0, 1, 1, 2, 3, 0, 5, 5, 4, 4, 1, 4, 1, 1, 5, 3,
|
||||
3, 1, 0, 3, 1, 2, 4, 5, 3, 4, 4, 0, 3, 5, 0, 3, 4, 1, 0, 1, 3, 4, 0, 5, 2, 5, 0, 4, 2, 2, 2, 2,
|
||||
4, 4, 5, 2, 1, 1, 5, 1, 4, 4, 5, 1, 2, 4, 0, 3, 1, 1, 0, 2, 1, 5, 2, 0, 1, 1, 5, 5, 4, 0, 0, 4,
|
||||
2, 3, 2, 1, 4, 0, 5, 0, 2, 3, 1, 2, 1, 2, 1, 4, 2, 3, 5, 5, 4, 5, 2, 0, 3, 0, 2, 0, 1, 3, 0, 4,
|
||||
1, 5, 2, 5, 4, 2, 5, 1, 4, 5, 3, 1, 0, 4, 4, 4, 1, 3, 4, 2, 2, 4, 1, 4, 0, 1, 0, 2, 4, 5, 2, 1,
|
||||
0, 3, 5, 2, 4, 2, 1, 4, 2, 0, 1, 0, 2, 3, 0, 3, 2, 5, 5, 4, 3, 0, 0, 2, 0, 1, 5, 2, 2, 1, 3, 0,
|
||||
3, 0, 5, 3, 3, 3, 5, 5, 3, 4, 0, 1, 2, 1, 2, 4, 3, 5, 4, 3, 0, 0, 4, 4, 2, 3, 5, 4, 3, 5, 1, 2,
|
||||
1, 5, 0, 5, 1, 1, 5, 5, 0, 0, 1, 3, 2, 2, 2, 3, 4, 2, 2, 3, 2, 4, 3, 0, 2, 0, 3, 2, 1, 5, 2, 4,
|
||||
4, 5, 2, 5, 0, 5, 3, 3, 0, 3, 2, 5, 5, 1, 1, 0, 2, 3, 0, 1, 1, 2, 4, 1, 3, 3, 5, 5, 0, 1, 0, 0,
|
||||
1, 2, 3, 3, 5, 2, 2, 5, 1, 4, 3, 3, 0, 2, 5, 4, 3, 1, 2, 4, 0, 2, 1, 3, 1, 2, 1, 0, 5, 5, 4, 5};
|
||||
memcpy(weight_t->MutableData(), weight, sizeof(float) * weight_t->ElementsNum());
|
||||
inputs_->push_back(weight_t);
|
||||
|
||||
Tensor *out_t = new Tensor(kNumberTypeFloat, {1, 16}, schema::Format_NHWC, lite::Tensor::Category::CONST);
|
||||
out_t->MallocData();
|
||||
outputs_->push_back(out_t);
|
||||
|
||||
matmal_param->b_transpose_ = true;
|
||||
matmal_param->a_transpose_ = false;
|
||||
matmal_param->has_bias_ = false;
|
||||
matmal_param->act_type_ = ActType_No;
|
||||
return out_t->ElementsNum();
|
||||
}
|
||||
|
||||
TEST_F(TestFcFp32, FcTest3) {
|
||||
std::vector<lite::Tensor *> inputs_;
|
||||
std::vector<lite::Tensor *> outputs_;
|
||||
auto matmul_param = new MatMulParameter();
|
||||
float *correct;
|
||||
int total_size = FcTestInit3(&inputs_, &outputs_, matmul_param, &correct);
|
||||
lite::InnerContext *ctx = new lite::InnerContext;
|
||||
ctx->thread_num_ = 1;
|
||||
ASSERT_EQ(lite::RET_OK, ctx->Init());
|
||||
kernel::FullconnectionCPUKernel *fc =
|
||||
new kernel::FullconnectionCPUKernel(reinterpret_cast<OpParameter *>(matmul_param), inputs_, outputs_, ctx, nullptr);
|
||||
|
||||
fc->Init();
|
||||
struct timeval start, end;
|
||||
gettimeofday(&start, NULL);
|
||||
for (int i = 0; i < 100000; ++i) fc->Run();
|
||||
gettimeofday(&end, NULL);
|
||||
// printf("## elapsed: %llu\n", 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - end.tv_usec);
|
||||
}
|
||||
|
||||
} // namespace mindspore
|
||||
|
|
Loading…
Reference in New Issue