mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-29 02:52:55 +08:00
Merge pull request #687 from joey12300/add_tile_linespace_functions
[Functions] Add fdtensor functions
This commit is contained in:
78
fastdeploy/function/cumprod.cc
Normal file
78
fastdeploy/function/cumprod.cc
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/function/cumprod.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
void GetCumprodDimInfo(const std::vector<int64_t>& dim, int cumprod_dim,
|
||||
size_t* outer_dim, size_t* mid_dim, size_t* inner_dim) {
|
||||
int dim_size = dim.size();
|
||||
FDASSERT(cumprod_dim >= -dim_size,
|
||||
"The input dim of CumprodOp should be larger than the opposite "
|
||||
"rank of input x which is %d. But received dim = %d",
|
||||
-dim_size, cumprod_dim);
|
||||
FDASSERT(cumprod_dim < dim_size,
|
||||
"The input dim of CumprodOp should be smaller than the "
|
||||
"rank of input x which is %d. But received dim = %d",
|
||||
dim_size, cumprod_dim);
|
||||
if (cumprod_dim < 0)
|
||||
cumprod_dim += dim_size;
|
||||
|
||||
*outer_dim = 1;
|
||||
for (int i = 0; i < cumprod_dim; ++i) {
|
||||
*outer_dim *= dim[i];
|
||||
}
|
||||
*mid_dim = dim[cumprod_dim];
|
||||
*inner_dim = 1;
|
||||
for (int i = cumprod_dim + 1; i < dim_size; ++i) {
|
||||
*inner_dim *= dim[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void CumprodKernel(const FDTensor& x, FDTensor* out, int axis) {
|
||||
auto* x_data = reinterpret_cast<const T*>(x.Data());
|
||||
auto shape = x.Shape();
|
||||
|
||||
size_t outer_dim = 1;
|
||||
size_t mid_dim = 1;
|
||||
size_t inner_dim = 1;
|
||||
GetCumprodDimInfo(shape, axis, &outer_dim, &mid_dim, &inner_dim);
|
||||
|
||||
out->Allocate(x.Shape(), x.Dtype());
|
||||
auto* out_data = reinterpret_cast<T*>(out->Data());
|
||||
|
||||
for (size_t i = 0; i < outer_dim; i++) {
|
||||
for (size_t j = 0; j < mid_dim; j++) {
|
||||
for (size_t k = 0; k < inner_dim; k++) {
|
||||
size_t pos = i * mid_dim * inner_dim + j * inner_dim + k;
|
||||
if (j == 0) {
|
||||
out_data[pos] = x_data[pos];
|
||||
} else {
|
||||
out_data[pos] = out_data[pos - inner_dim] * x_data[pos];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cumprod(const FDTensor& x, FDTensor* out, int axis) {
|
||||
FD_VISIT_INT_FLOAT_TYPES(x.dtype, "CumprodKernel",
|
||||
([&] { CumprodKernel<data_t>(x, out, axis); }));
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
31
fastdeploy/function/cumprod.h
Normal file
31
fastdeploy/function/cumprod.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
/** Excute the concatenate operation for input FDTensor along given axis.
|
||||
@param x The input tensor.
|
||||
@param out The output tensor which stores the result.
|
||||
@param axisi Axis which will be concatenated.
|
||||
*/
|
||||
|
||||
FASTDEPLOY_DECL void Cumprod(const FDTensor& x, FDTensor* out, int axis = 0);
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
52
fastdeploy/function/linspace.cc
Normal file
52
fastdeploy/function/linspace.cc
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/function/linspace.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
template <typename T>
|
||||
void LinspaceKernel(double start, double end, int num, FDTensor* out) {
|
||||
FDASSERT(
|
||||
num > 0,
|
||||
"The num of linspace op should be larger than 0, but received num is %d",
|
||||
num);
|
||||
out->Allocate({num}, TypeToDataType<T>::dtype);
|
||||
T* out_data = reinterpret_cast<T*>(out->Data());
|
||||
if (num > 1) {
|
||||
// step should be of double type for all types
|
||||
double step = (static_cast<double>(end - start)) / (num - 1);
|
||||
int half_num = num / 2;
|
||||
for (int i = 0; i < num; ++i) {
|
||||
if (i < half_num) {
|
||||
out_data[i] = static_cast<T>(start + step * i);
|
||||
} else {
|
||||
out_data[i] = static_cast<T>(end - step * (num - i - 1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out_data[0] = static_cast<T>(start);
|
||||
}
|
||||
}
|
||||
|
||||
void Linspace(double start, double end, int num, FDTensor* out,
|
||||
FDDataType dtype) {
|
||||
FD_VISIT_INT_FLOAT_TYPES(dtype, "LinspaceKernel", ([&] {
|
||||
LinspaceKernel<data_t>(start, end, num, out);
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
33
fastdeploy/function/linspace.h
Normal file
33
fastdeploy/function/linspace.h
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
/** Return fixed number of evenly spaced values within a given interval.
|
||||
@param start The input start is start variable of range.
|
||||
@param end The input stop is start variable of range.
|
||||
@param num The input num is given num of the sequence.
|
||||
@param out The output tensor which stores the result.
|
||||
@param dtype The data type of output tensor, default to float32.
|
||||
*/
|
||||
FASTDEPLOY_DECL void Linspace(double start, double end, int num, FDTensor* out,
|
||||
FDDataType dtype = FDDataType::FP32);
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
@@ -39,6 +39,7 @@ DEFINE_ACTIVATION_KERNEL(Sqrt, SqrtFunctor)
|
||||
DEFINE_ACTIVATION_KERNEL(Log, LogFunctor)
|
||||
DEFINE_ACTIVATION_KERNEL(Round, RoundFunctor)
|
||||
DEFINE_ACTIVATION_KERNEL(Exp, ExpFunctor)
|
||||
DEFINE_ACTIVATION_KERNEL(Abs, AbsFunctor)
|
||||
|
||||
void Sqrt(const FDTensor& x, FDTensor* out) {
|
||||
FD_VISIT_FLOAT_TYPES(x.dtype, "SqrtKernel",
|
||||
@@ -60,5 +61,10 @@ void Exp(const FDTensor& x, FDTensor* out) {
|
||||
([&] { ExpKernel<data_t>(x, out); }));
|
||||
}
|
||||
|
||||
void Abs(const FDTensor& x, FDTensor* out) {
|
||||
FD_VISIT_FLOAT_TYPES(x.dtype, "AbsKernel",
|
||||
([&] { AbsKernel<data_t>(x, out); }));
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
@@ -43,5 +43,11 @@ FASTDEPLOY_DECL void Round(const FDTensor& x, FDTensor* out);
|
||||
*/
|
||||
FASTDEPLOY_DECL void Exp(const FDTensor& x, FDTensor* out);
|
||||
|
||||
/** This operator is used to perform elementwise abs for input X. Only for float type FDTensor
|
||||
@param x The input tensor.
|
||||
@param out The output tensor which stores the result.
|
||||
*/
|
||||
FASTDEPLOY_DECL void Abs(const FDTensor& x, FDTensor* out);
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
|
||||
@@ -52,5 +52,14 @@ template <typename T> struct SqrtFunctor {
|
||||
}
|
||||
};
|
||||
|
||||
// abs(x) = x if x > 0 else -x
|
||||
template <typename T> struct AbsFunctor {
|
||||
template <typename Device, typename X, typename Out>
|
||||
void operator()(Device d, X x, Out out) const {
|
||||
out.device(d) =
|
||||
x.unaryExpr([](T v) { return v > static_cast<T>(0) ? v : -v; });
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
|
||||
160
fastdeploy/function/split.cc
Normal file
160
fastdeploy/function/split.cc
Normal file
@@ -0,0 +1,160 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/function/split.h"
|
||||
#include "fastdeploy/utils/utils.h"
|
||||
#include <cstring>
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
/*
|
||||
* All tensors' dimension should be the same and the values of
|
||||
* each dimension must be the same, except the axis dimension.
|
||||
*/
|
||||
template <typename T> struct SplitFunctor {
|
||||
public:
|
||||
void operator()(const FDTensor& input,
|
||||
const std::vector<const FDTensor*>& ref_inputs, int axis,
|
||||
std::vector<FDTensor>* outputs) {
|
||||
if (input.Numel() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t num = outputs->size();
|
||||
|
||||
int input_rows = 1;
|
||||
auto dim_0 = ref_inputs[0]->Shape();
|
||||
for (int i = 0; i < axis; ++i) {
|
||||
input_rows *= dim_0[i];
|
||||
}
|
||||
|
||||
int input_cols = 0;
|
||||
|
||||
std::vector<int64_t> output_cols(outputs->size());
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
int t_cols = ref_inputs[i]->Numel() / input_rows;
|
||||
input_cols += t_cols;
|
||||
output_cols[i] = t_cols;
|
||||
}
|
||||
|
||||
// computation
|
||||
for (int k = 0; k < input_rows; ++k) {
|
||||
const T* src_ptr =
|
||||
reinterpret_cast<const T*>(input.Data()) + k * input_cols;
|
||||
int col_idx = 0;
|
||||
for (size_t j = 0; j < num; ++j) {
|
||||
int col_len = output_cols[j];
|
||||
auto* out_tensor = &(outputs->at(j));
|
||||
if (out_tensor != nullptr) {
|
||||
T* dst_ptr = reinterpret_cast<T*>(out_tensor->Data()) + k * col_len;
|
||||
std::memcpy(dst_ptr, src_ptr + col_idx, sizeof(T) * col_len);
|
||||
}
|
||||
col_idx += col_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline int GetSplitAxisValue(const FDTensor& x, int axis) {
|
||||
int rank = x.Shape().size();
|
||||
FDASSERT(axis >= -rank && axis < rank,
|
||||
"The axis is expected to be in range of [%d, %d), but got %d", -rank,
|
||||
rank, axis);
|
||||
if (axis < 0) {
|
||||
axis = axis + rank;
|
||||
}
|
||||
return axis;
|
||||
}
|
||||
|
||||
void CreateSplitOutputs(const FDTensor& x,
|
||||
const std::vector<int>& sections_data,
|
||||
std::vector<FDTensor>* outs, int axis) {
|
||||
axis = GetSplitAxisValue(x, axis);
|
||||
auto input_axis_dim = x.Shape().at(axis);
|
||||
std::vector<int> sections_vec;
|
||||
const int unknow_dim_val = -1;
|
||||
int unknow_dim_idx = -1;
|
||||
int num_of_unknow = 0;
|
||||
int sum_of_section = 0;
|
||||
|
||||
for (size_t i = 0; i < sections_data.size(); ++i) {
|
||||
sections_vec.push_back(sections_data[i]);
|
||||
if (sections_data[i] == unknow_dim_val) {
|
||||
num_of_unknow++;
|
||||
unknow_dim_idx = i;
|
||||
} else {
|
||||
sum_of_section += sections_data[i];
|
||||
}
|
||||
}
|
||||
|
||||
FDASSERT(num_of_unknow <= 1,
|
||||
"Only one dimension value of Attr(num_or_sections) "
|
||||
"in SplitOp can be -1. "
|
||||
"But received Attr(num_or_sections) = [%s].",
|
||||
Str(sections_data).c_str());
|
||||
if (unknow_dim_idx != -1) {
|
||||
// for example, input shape = [4 ,5], axis = 1, sections = [2, 3, -1].
|
||||
// input_axis_dim = 5, sum_of_sections = 5.
|
||||
// the following check will fail.
|
||||
FDASSERT(sum_of_section < input_axis_dim,
|
||||
"Sum of Attr(num_or_sections) other than unknown section "
|
||||
"must be less than the input's "
|
||||
"size "
|
||||
"along the split dimension. But received Attr(num_or_sections) "
|
||||
"= [%s], input(X)'s shape = [%s], Attr(dim) = %d.",
|
||||
Str(sections_data).c_str(), Str(x.Shape()).c_str(), axis);
|
||||
sections_vec[unknow_dim_idx] = input_axis_dim - sum_of_section;
|
||||
} else {
|
||||
FDASSERT(sum_of_section == input_axis_dim,
|
||||
"Sum of Attr(num_or_sections) must be equal to the input's "
|
||||
"size "
|
||||
"along the split dimension. But received Attr(num_or_sections)"
|
||||
" = [%s], input(X)'s shape = [%s], Attr(dim) = %d.",
|
||||
Str(sections_data).c_str(), Str(x.Shape()).c_str(), axis);
|
||||
}
|
||||
// fill out dims
|
||||
std::vector<std::vector<int64_t>> out_dims(sections_vec.size(), x.Shape());
|
||||
for (size_t i = 0; i < sections_vec.size(); ++i) {
|
||||
out_dims[i][axis] = sections_vec[i];
|
||||
}
|
||||
for (size_t i = 0; i < sections_vec.size(); ++i) {
|
||||
(*outs)[i].Allocate(out_dims[i], x.Dtype());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void SplitKernel(const FDTensor& x, const std::vector<int>& section,
|
||||
std::vector<FDTensor>* outs, int axis) {
|
||||
size_t out_number = section.size();
|
||||
outs->resize(out_number);
|
||||
CreateSplitOutputs(x, section, outs, axis);
|
||||
|
||||
std::vector<const FDTensor*> shape_refer;
|
||||
for (size_t j = 0; j < outs->size(); ++j) {
|
||||
shape_refer.emplace_back(&((*outs)[j]));
|
||||
}
|
||||
SplitFunctor<T> functor;
|
||||
functor(x, shape_refer, axis, outs);
|
||||
}
|
||||
|
||||
void Split(const FDTensor& x, const std::vector<int>& num_or_sections,
|
||||
std::vector<FDTensor>* out, int axis) {
|
||||
FD_VISIT_ALL_TYPES(x.Dtype(), "Split", ([&] {
|
||||
SplitKernel<data_t>(x, num_or_sections, out, axis);
|
||||
}));
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
36
fastdeploy/function/split.h
Normal file
36
fastdeploy/function/split.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
/** Split the input tensor into multiple sub-Tensors.
|
||||
@param x The input tensor.
|
||||
@param num_or_sections f num_or_sections is an int, then num_or_sections
|
||||
indicates the number of equal sized sub-Tensors that the x will
|
||||
be divided into.
|
||||
@param out The output vector tensor which stores the result.
|
||||
@param axis Axis which will be splitted.
|
||||
*/
|
||||
|
||||
FASTDEPLOY_DECL void Split(const FDTensor& x,
|
||||
const std::vector<int>& num_or_sections,
|
||||
std::vector<FDTensor>* out, int axis = 0);
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
108
fastdeploy/function/tile.cc
Normal file
108
fastdeploy/function/tile.cc
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/function/tile.h"
|
||||
#include "fastdeploy/function/eigen.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
template <typename T, int Rank>
|
||||
void TileFunctor(const FDTensor& x,
|
||||
const std::vector<int64_t>& origin_repeat_times,
|
||||
FDTensor* out) {
|
||||
auto x_shape = x.Shape();
|
||||
auto repeat_times = origin_repeat_times;
|
||||
for (size_t i = 0; i < repeat_times.size(); ++i) {
|
||||
FDASSERT(repeat_times[i] > 0,
|
||||
"All elements of the input 'repeat_times' "
|
||||
"for tile op must be positive integers, but "
|
||||
"the value received is %d.",
|
||||
repeat_times[i]);
|
||||
}
|
||||
if (repeat_times.size() < x_shape.size()) {
|
||||
int diff = x_shape.size() - repeat_times.size();
|
||||
repeat_times.insert(repeat_times.begin(), diff, 1);
|
||||
} else {
|
||||
int diff = repeat_times.size() - x_shape.size();
|
||||
x_shape.insert(x_shape.begin(), diff, 1);
|
||||
}
|
||||
FDASSERT(repeat_times.size() == x_shape.size(),
|
||||
"The rank (%d) of the input 'x' and the rank (%d) of the input "
|
||||
"'repeat_times' for tile op must match after promotion.",
|
||||
x_shape.size(), repeat_times.size());
|
||||
|
||||
if (Rank == 0) {
|
||||
// Deep copy
|
||||
*out = x;
|
||||
return;
|
||||
}
|
||||
|
||||
Eigen::DSizes<Eigen::DenseIndex, Rank> bcast_dims;
|
||||
for (size_t i = 0; i < repeat_times.size(); ++i) {
|
||||
bcast_dims[i] = repeat_times[i];
|
||||
}
|
||||
|
||||
std::vector<int64_t> out_shape(x_shape);
|
||||
for (size_t i = 0; i < repeat_times.size(); ++i) {
|
||||
out_shape[i] *= repeat_times[i];
|
||||
}
|
||||
|
||||
out->Allocate(out_shape, x.Dtype());
|
||||
auto eigen_x = EigenTensor<T, Rank>::From(x, x_shape);
|
||||
auto eigen_out = EigenTensor<T, Rank>::From(*out, out_shape);
|
||||
|
||||
const auto& dev = *EigenDeviceWrapper::GetInstance()->GetDevice();
|
||||
eigen_out.device(dev) = eigen_x.broadcast(bcast_dims);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TileKernel(const FDTensor& x, const std::vector<int64_t>& repeat_times,
|
||||
FDTensor* out) {
|
||||
auto rank = x.Shape().size();
|
||||
auto repeat_times_size = repeat_times.size();
|
||||
rank = (std::max)(rank, repeat_times_size);
|
||||
switch (rank) {
|
||||
case 0:
|
||||
*out = x;
|
||||
break;
|
||||
case 1:
|
||||
TileFunctor<T, 1>(x, repeat_times, out);
|
||||
break;
|
||||
case 2:
|
||||
TileFunctor<T, 2>(x, repeat_times, out);
|
||||
break;
|
||||
case 3:
|
||||
TileFunctor<T, 3>(x, repeat_times, out);
|
||||
break;
|
||||
case 4:
|
||||
TileFunctor<T, 4>(x, repeat_times, out);
|
||||
break;
|
||||
case 5:
|
||||
TileFunctor<T, 5>(x, repeat_times, out);
|
||||
break;
|
||||
case 6:
|
||||
TileFunctor<T, 6>(x, repeat_times, out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Tile(const FDTensor& x, const std::vector<int64_t>& repeat_times,
|
||||
FDTensor* out) {
|
||||
FD_VISIT_ALL_TYPES(x.dtype, "TileKernel",
|
||||
([&] { TileKernel<data_t>(x, repeat_times, out); }));
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
36
fastdeploy/function/tile.h
Normal file
36
fastdeploy/function/tile.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
/** Construct a new Tensor by repeating x the number of times given by
|
||||
** repeat_times. After tiling, the value of the i’th dimension of the
|
||||
** output is equal to x.shape[i]*repeat_times[i]. Both the number of
|
||||
** dimensions of x and the number of elements in repeat_times should
|
||||
** be less than or equal to 6.Support all data types.
|
||||
@param x The input tensor.
|
||||
@param repeat_times The lower bound
|
||||
@param out The output tensor which stores the result.
|
||||
*/
|
||||
FASTDEPLOY_DECL void Tile(const FDTensor& x,
|
||||
const std::vector<int64_t>& repeat_times,
|
||||
FDTensor* out);
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
@@ -63,14 +63,4 @@ std::vector<int64_t> GetStride(const std::vector<int64_t>& dims) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Str(const std::vector<int64_t>& shape) {
|
||||
std::ostringstream oss;
|
||||
oss << "[ " << shape[0];
|
||||
for (int i = 1; i < shape.size(); ++i) {
|
||||
oss << " ," << shape[i];
|
||||
}
|
||||
oss << " ]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
} // namespace fastdeploy
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <numeric>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -195,6 +196,16 @@ FASTDEPLOY_DECL bool ReadBinaryFromFile(const std::string& file,
|
||||
FASTDEPLOY_DECL std::vector<int64_t>
|
||||
GetStride(const std::vector<int64_t>& dims);
|
||||
|
||||
FASTDEPLOY_DECL std::string Str(const std::vector<int64_t>& shape);
|
||||
template <typename T, typename std::enable_if<std::is_integral<T>::value,
|
||||
bool>::type = true>
|
||||
std::string Str(const std::vector<T>& shape) {
|
||||
std::ostringstream oss;
|
||||
oss << "[ " << shape[0];
|
||||
for (int i = 1; i < shape.size(); ++i) {
|
||||
oss << " ," << shape[i];
|
||||
}
|
||||
oss << " ]";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
} // namespace fastdeploy
|
||||
|
||||
73
tests/function/test_cumprod.cc
Normal file
73
tests/function/test_cumprod.cc
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
#include "fastdeploy/function/cumprod.h"
|
||||
#include "glog/logging.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
std::vector<float> CreateTestData() {
|
||||
// Shape: [2, 3, 4]
|
||||
std::vector<float> x_data = {
|
||||
0.8428625, 0.6461913, 0.13740455, 0.11430702, 0.659926, 0.535816,
|
||||
0.7429162, 0.8456049, 0.21228176, 0.29970083, 0.8621713, 0.40894133,
|
||||
0.12684688, 0.1566195, 0.42884097, 0.8476526, 0.2458633, 0.669046,
|
||||
0.87888306, 0.6762589, 0.666453, 0.32523027, 0.4139388, 0.8341406};
|
||||
return x_data;
|
||||
}
|
||||
|
||||
TEST(fastdeploy, cumprod) {
|
||||
CheckShape check_shape;
|
||||
CheckData check_data;
|
||||
FDTensor x, y;
|
||||
auto test_data = CreateTestData();
|
||||
x.SetExternalData({2, 3, 4}, FDDataType::FP32, test_data.data());
|
||||
|
||||
std::vector<float> result = {0.842862, 0.646191, 0.137405, 0.114307, 0.659926,
|
||||
0.535816, 0.742916, 0.845605, 0.212282, 0.299701,
|
||||
0.862171, 0.408941, 0.106914, 0.101206, 0.058925,
|
||||
0.096893, 0.162252, 0.358486, 0.652937, 0.571848,
|
||||
0.141476, 0.097472, 0.356886, 0.341115};
|
||||
Cumprod(x, &y, 0);
|
||||
check_shape(y.shape, {2, 3, 4});
|
||||
check_data(reinterpret_cast<const float*>(y.Data()), result.data(),
|
||||
result.size());
|
||||
|
||||
result = {0.842862, 0.646191, 0.137405, 0.114307, 0.556227, 0.34624,
|
||||
0.10208, 0.096659, 0.118077, 0.103768, 0.088011, 0.039528,
|
||||
0.126847, 0.15662, 0.428841, 0.847653, 0.031187, 0.104786,
|
||||
0.376901, 0.573233, 0.020785, 0.034079, 0.156014, 0.478157};
|
||||
Cumprod(x, &y, 1);
|
||||
check_shape(y.shape, {2, 3, 4});
|
||||
check_data(reinterpret_cast<const float*>(y.Data()), result.data(),
|
||||
result.size());
|
||||
|
||||
result = {0.842862, 0.54465, 0.074837, 0.008554, 0.659926, 0.353599,
|
||||
0.262694, 0.222136, 0.212282, 0.063621, 0.054852, 0.022431,
|
||||
0.126847, 0.019867, 0.00852, 0.007222, 0.245863, 0.164494,
|
||||
0.144571, 0.097767, 0.666453, 0.216751, 0.089722, 0.07484};
|
||||
Cumprod(x, &y, 2);
|
||||
check_shape(y.shape, {2, 3, 4});
|
||||
check_data(reinterpret_cast<const float*>(y.Data()), result.data(),
|
||||
result.size());
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
53
tests/function/test_linspace.cc
Normal file
53
tests/function/test_linspace.cc
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
#include "fastdeploy/function/linspace.h"
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
TEST(fastdeploy, linspace) {
|
||||
CheckShape check_shape;
|
||||
CheckData check_data;
|
||||
|
||||
FDTensor x;
|
||||
|
||||
std::vector<float> result = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
Linspace(0, 10, 11, &x);
|
||||
check_shape({11}, x.Shape());
|
||||
check_data(reinterpret_cast<const float*>(x.Data()), result.data(),
|
||||
result.size());
|
||||
|
||||
result = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
|
||||
Linspace(10, 0, 11, &x);
|
||||
check_shape({11}, x.Shape());
|
||||
check_data(reinterpret_cast<const float*>(x.Data()), result.data(),
|
||||
result.size());
|
||||
|
||||
result = {10};
|
||||
Linspace(10, 0, 1, &x);
|
||||
check_shape({1}, x.Shape());
|
||||
check_data(reinterpret_cast<const float*>(x.Data()), result.data(),
|
||||
result.size());
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
@@ -83,5 +83,18 @@ TEST(fastdeploy, exp_sqrt_round_log) {
|
||||
log_result.size());
|
||||
}
|
||||
|
||||
TEST(fastdeploy, abs) {
|
||||
CheckShape check_shape;
|
||||
CheckData check_data;
|
||||
FDTensor x, y;
|
||||
std::vector<float> test_data = {-1, 2, 3, -5, -4, -6};
|
||||
x.SetExternalData({2, 3}, FDDataType::FP32, test_data.data());
|
||||
std::vector<float> result = {1, 2, 3, 5, 4, 6};
|
||||
Abs(x, &y);
|
||||
check_shape(y.shape, {2, 3});
|
||||
check_data(reinterpret_cast<const float*>(y.Data()), result.data(),
|
||||
result.size());
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
113
tests/function/test_split.cc
Normal file
113
tests/function/test_split.cc
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
#include "fastdeploy/function/split.h"
|
||||
#include "glog/logging.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
std::vector<float> CreateTestData() {
|
||||
// Shape: [2, 3, 4]
|
||||
std::vector<float> x_data = {
|
||||
0.8428625, 0.6461913, 0.13740455, 0.11430702, 0.659926, 0.535816,
|
||||
0.7429162, 0.8456049, 0.21228176, 0.29970083, 0.8621713, 0.40894133,
|
||||
0.12684688, 0.1566195, 0.42884097, 0.8476526, 0.2458633, 0.669046,
|
||||
0.87888306, 0.6762589, 0.666453, 0.32523027, 0.4139388, 0.8341406};
|
||||
return x_data;
|
||||
}
|
||||
|
||||
TEST(fastdeploy, split_axis0) {
|
||||
CheckShape check_shape;
|
||||
CheckData check_data;
|
||||
FDTensor x;
|
||||
std::vector<FDTensor> out;
|
||||
auto test_data = CreateTestData();
|
||||
x.SetExternalData({2, 3, 4}, FDDataType::FP32, test_data.data());
|
||||
|
||||
Split(x, {1, 1}, &out, 0);
|
||||
ASSERT_EQ(out.size(), 2);
|
||||
check_shape(out[0].Shape(), {1, 3, 4});
|
||||
check_shape(out[1].Shape(), {1, 3, 4});
|
||||
std::vector<float> result1 = {0.842862, 0.646191, 0.137405, 0.114307,
|
||||
0.659926, 0.535816, 0.742916, 0.845605,
|
||||
0.212282, 0.299701, 0.862171, 0.408941};
|
||||
std::vector<float> result2 = {0.126847, 0.15662, 0.428841, 0.847653,
|
||||
0.245863, 0.669046, 0.878883, 0.676259,
|
||||
0.666453, 0.32523, 0.413939, 0.834141};
|
||||
check_data(reinterpret_cast<const float*>(out[0].Data()), result1.data(),
|
||||
result1.size());
|
||||
check_data(reinterpret_cast<const float*>(out[1].Data()), result2.data(),
|
||||
result2.size());
|
||||
}
|
||||
|
||||
TEST(fastdeploy, split_axis1) {
|
||||
CheckShape check_shape;
|
||||
CheckData check_data;
|
||||
FDTensor x;
|
||||
std::vector<FDTensor> out;
|
||||
auto test_data = CreateTestData();
|
||||
x.SetExternalData({2, 3, 4}, FDDataType::FP32, test_data.data());
|
||||
|
||||
Split(x, {2, 1}, &out, 1);
|
||||
ASSERT_EQ(out.size(), 2);
|
||||
check_shape(out[0].Shape(), {2, 2, 4});
|
||||
check_shape(out[1].Shape(), {2, 1, 4});
|
||||
std::vector<float> result1 = {0.842862, 0.646191, 0.137405, 0.114307,
|
||||
0.659926, 0.535816, 0.742916, 0.845605,
|
||||
0.126847, 0.15662, 0.428841, 0.847653,
|
||||
0.245863, 0.669046, 0.878883, 0.676259};
|
||||
std::vector<float> result2 = {0.212282, 0.299701, 0.862171, 0.408941,
|
||||
0.666453, 0.32523, 0.413939, 0.834141};
|
||||
check_data(reinterpret_cast<const float*>(out[0].Data()), result1.data(),
|
||||
result1.size());
|
||||
check_data(reinterpret_cast<const float*>(out[1].Data()), result2.data(),
|
||||
result2.size());
|
||||
}
|
||||
|
||||
TEST(fastdeploy, split_axis2) {
|
||||
CheckShape check_shape;
|
||||
CheckData check_data;
|
||||
FDTensor x;
|
||||
std::vector<FDTensor> out;
|
||||
auto test_data = CreateTestData();
|
||||
x.SetExternalData({2, 3, 4}, FDDataType::FP32, test_data.data());
|
||||
|
||||
Split(x, {1, 2, 1}, &out, 2);
|
||||
ASSERT_EQ(out.size(), 3);
|
||||
check_shape(out[0].Shape(), {2, 3, 1});
|
||||
check_shape(out[1].Shape(), {2, 3, 2});
|
||||
check_shape(out[2].Shape(), {2, 3, 1});
|
||||
std::vector<float> result1 = {0.842862, 0.659926, 0.212282,
|
||||
0.126847, 0.245863, 0.666453};
|
||||
std::vector<float> result2 = {0.646191, 0.137405, 0.535816, 0.742916,
|
||||
0.299701, 0.862171, 0.15662, 0.428841,
|
||||
0.669046, 0.878883, 0.32523, 0.413939};
|
||||
std::vector<float> result3 = {0.114307, 0.845605, 0.408941,
|
||||
0.847653, 0.676259, 0.834141};
|
||||
check_data(reinterpret_cast<const float*>(out[0].Data()), result1.data(),
|
||||
result1.size());
|
||||
check_data(reinterpret_cast<const float*>(out[1].Data()), result2.data(),
|
||||
result2.size());
|
||||
check_data(reinterpret_cast<const float*>(out[2].Data()), result3.data(),
|
||||
result3.size());
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
68
tests/function/test_tile.cc
Normal file
68
tests/function/test_tile.cc
Normal file
@@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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 "fastdeploy/core/fd_tensor.h"
|
||||
#include "fastdeploy/function/tile.h"
|
||||
#include "glog/logging.h"
|
||||
#include "gtest_utils.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <vector>
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace function {
|
||||
|
||||
std::vector<float> CreateTestData() {
|
||||
// Shape: [2, 3]
|
||||
std::vector<float> x_data = {0.8428625, 0.6461913, 0.13740455,
|
||||
0.11430702, 0.659926, 0.535816};
|
||||
return x_data;
|
||||
}
|
||||
|
||||
TEST(fastdeploy, tile) {
|
||||
CheckShape check_shape;
|
||||
CheckData check_data;
|
||||
FDTensor x, y;
|
||||
auto test_data = CreateTestData();
|
||||
x.SetExternalData({2, 3}, FDDataType::FP32, test_data.data());
|
||||
Tile(x, {2}, &y);
|
||||
std::vector<float> result = {0.842862, 0.646191, 0.137405, 0.842862,
|
||||
0.646191, 0.137405, 0.114307, 0.659926,
|
||||
0.535816, 0.114307, 0.659926, 0.535816};
|
||||
check_shape(y.Shape(), {2, 6});
|
||||
check_data(reinterpret_cast<const float*>(y.Data()), result.data(),
|
||||
result.size());
|
||||
|
||||
result = {0.842862, 0.646191, 0.137405, 0.842862, 0.646191, 0.137405,
|
||||
0.842862, 0.646191, 0.137405, 0.114307, 0.659926, 0.535816,
|
||||
0.114307, 0.659926, 0.535816, 0.114307, 0.659926, 0.535816,
|
||||
0.842862, 0.646191, 0.137405, 0.842862, 0.646191, 0.137405,
|
||||
0.842862, 0.646191, 0.137405, 0.114307, 0.659926, 0.535816,
|
||||
0.114307, 0.659926, 0.535816, 0.114307, 0.659926, 0.535816};
|
||||
Tile(x, {2, 3}, &y);
|
||||
check_shape(y.Shape(), {4, 9});
|
||||
check_data(reinterpret_cast<const float*>(y.Data()), result.data(),
|
||||
result.size());
|
||||
|
||||
result = {0.842862, 0.646191, 0.137405, 0.842862, 0.646191, 0.137405,
|
||||
0.114307, 0.659926, 0.535816, 0.114307, 0.659926, 0.535816,
|
||||
0.842862, 0.646191, 0.137405, 0.842862, 0.646191, 0.137405,
|
||||
0.114307, 0.659926, 0.535816, 0.114307, 0.659926, 0.535816,
|
||||
0.842862, 0.646191, 0.137405, 0.842862, 0.646191, 0.137405,
|
||||
0.114307, 0.659926, 0.535816, 0.114307, 0.659926, 0.535816};
|
||||
Tile(x, {3, 2}, &y);
|
||||
check_shape(y.Shape(), {6, 6});
|
||||
}
|
||||
|
||||
} // namespace function
|
||||
} // namespace fastdeploy
|
||||
Reference in New Issue
Block a user