mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-18 14:40:44 +08:00
[Functions] Add +-*/ operators and reshape for FDTensor (#655)
* Add +-*/ functions * Add same dims test case for operations * add broadcast 0 * Add broadcast dim2 testcase * Add broadcast dim3 and dim4 testcase * Add +-*/ operators * Add mixed operation * refresh code style * Add reshape op * update code style
This commit is contained in:
95
fastdeploy/core/fd_tensor.cc
Executable file → Normal file
95
fastdeploy/core/fd_tensor.cc
Executable file → Normal file
@@ -11,11 +11,11 @@
|
||||
// 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 <cstring>
|
||||
|
||||
#include "fastdeploy/core/fd_tensor.h"
|
||||
#include "fastdeploy/core/float16.h"
|
||||
#include "fastdeploy/utils/utils.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#ifdef WITH_GPU
|
||||
#include <cuda_runtime_api.h>
|
||||
#endif
|
||||
@@ -151,9 +151,63 @@ void FDTensor::Resize(const std::vector<int64_t>& new_shape,
|
||||
shape.assign(new_shape.begin(), new_shape.end());
|
||||
}
|
||||
|
||||
bool FDTensor::Reshape(const std::vector<int64_t>& new_shape) {
|
||||
int numel = Numel();
|
||||
const int64_t unk_dim_val = -1;
|
||||
const int64_t copy_dim_val = 0;
|
||||
|
||||
std::vector<int64_t> output_shape(new_shape.size(), 0);
|
||||
int64_t capacity = 1;
|
||||
int unk_dim_idx = -1;
|
||||
for (size_t i = 0; i < new_shape.size(); ++i) {
|
||||
if (new_shape[i] == unk_dim_val) {
|
||||
FDASSERT(unk_dim_idx == -1,
|
||||
"Only one dimension value of 'shape' in ReshapeOp can "
|
||||
"be -1. But received shape = [%s], shape[%d] is also -1.",
|
||||
Str(new_shape).c_str(), i);
|
||||
unk_dim_idx = i;
|
||||
} else if (new_shape[i] == copy_dim_val) {
|
||||
FDASSERT(i < shape.size(),
|
||||
"The index of 0 in `shape` must be less than "
|
||||
"the input tensor X's dimensions. "
|
||||
"But received shape = [%s], shape[%d] = 0, X's shape = [%s], "
|
||||
"X's dimensions = %d.",
|
||||
Str(new_shape).c_str(), i, Str(shape).c_str(), shape.size());
|
||||
} else {
|
||||
FDASSERT(new_shape[i] > 0,
|
||||
"Each dimension value of 'shape' in ReshapeOp must not "
|
||||
"be negative except one unknown dimension. "
|
||||
"But received shape = [%s], shape[%d] = %d.",
|
||||
Str(new_shape).c_str(), i, new_shape[i]);
|
||||
}
|
||||
capacity *= (new_shape[i] ? new_shape[i] : shape[i]);
|
||||
output_shape[i] = (new_shape[i] ? new_shape[i] : shape[i]);
|
||||
}
|
||||
if (unk_dim_idx != -1) {
|
||||
output_shape[unk_dim_idx] = -numel / capacity;
|
||||
FDASSERT(output_shape[unk_dim_idx] * capacity == -numel,
|
||||
"The 'shape' attribute in ReshapeOp is invalid. "
|
||||
"The input tensor X'size must be divisible by known "
|
||||
"capacity of 'shape'. "
|
||||
"But received X's shape = [%s], X's size = %d, "
|
||||
"'shape' is [%s], known capacity of 'shape' is %d.",
|
||||
Str(shape).c_str(), numel, Str(new_shape).c_str(), capacity);
|
||||
} else {
|
||||
FDASSERT(numel == capacity,
|
||||
"The 'shape' in ReshapeOp is invalid. "
|
||||
"The input tensor X'size must be equal to the capacity of "
|
||||
"'shape'. "
|
||||
"But received X's shape = [%s], X's size = %d, 'shape' is "
|
||||
"[%s], the capacity of 'shape' is %d.",
|
||||
Str(shape).c_str(), numel, Str(shape).c_str(), capacity);
|
||||
}
|
||||
shape = output_shape;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void CalculateStatisInfo(const void* src_ptr, int size, double* mean, double* max,
|
||||
double* min) {
|
||||
void CalculateStatisInfo(const void* src_ptr, int size, double* mean,
|
||||
double* max, double* min) {
|
||||
const T* ptr = static_cast<const T*>(src_ptr);
|
||||
*mean = 0;
|
||||
*max = -99999999;
|
||||
@@ -213,10 +267,9 @@ bool FDTensor::ReallocFn(size_t nbytes) {
|
||||
}
|
||||
return buffer_ != nullptr;
|
||||
#else
|
||||
FDASSERT(false,
|
||||
"The FastDeploy FDTensor allocator didn't compile under "
|
||||
"-DWITH_GPU=ON,"
|
||||
"so this is an unexpected problem happend.");
|
||||
FDASSERT(false, "The FastDeploy FDTensor allocator didn't compile under "
|
||||
"-DWITH_GPU=ON,"
|
||||
"so this is an unexpected problem happend.");
|
||||
#endif
|
||||
} else {
|
||||
if (is_pinned_memory) {
|
||||
@@ -230,10 +283,9 @@ bool FDTensor::ReallocFn(size_t nbytes) {
|
||||
}
|
||||
return buffer_ != nullptr;
|
||||
#else
|
||||
FDASSERT(false,
|
||||
"The FastDeploy FDTensor allocator didn't compile under "
|
||||
"-DWITH_GPU=ON,"
|
||||
"so this is an unexpected problem happend.");
|
||||
FDASSERT(false, "The FastDeploy FDTensor allocator didn't compile under "
|
||||
"-DWITH_GPU=ON,"
|
||||
"so this is an unexpected problem happend.");
|
||||
#endif
|
||||
}
|
||||
buffer_ = realloc(buffer_, nbytes);
|
||||
@@ -242,7 +294,8 @@ bool FDTensor::ReallocFn(size_t nbytes) {
|
||||
}
|
||||
|
||||
void FDTensor::FreeFn() {
|
||||
if (external_data_ptr != nullptr) external_data_ptr = nullptr;
|
||||
if (external_data_ptr != nullptr)
|
||||
external_data_ptr = nullptr;
|
||||
if (buffer_ != nullptr) {
|
||||
if (device == Device::GPU) {
|
||||
#ifdef WITH_GPU
|
||||
@@ -293,11 +346,8 @@ void FDTensor::CopyBuffer(void* dst, const void* src, size_t nbytes,
|
||||
FDTensor::FDTensor(const std::string& tensor_name) { name = tensor_name; }
|
||||
|
||||
FDTensor::FDTensor(const FDTensor& other)
|
||||
: shape(other.shape),
|
||||
name(other.name),
|
||||
dtype(other.dtype),
|
||||
device(other.device),
|
||||
external_data_ptr(other.external_data_ptr) {
|
||||
: shape(other.shape), name(other.name), dtype(other.dtype),
|
||||
device(other.device), external_data_ptr(other.external_data_ptr) {
|
||||
// Copy buffer
|
||||
if (other.buffer_ == nullptr) {
|
||||
buffer_ = nullptr;
|
||||
@@ -310,12 +360,9 @@ FDTensor::FDTensor(const FDTensor& other)
|
||||
}
|
||||
|
||||
FDTensor::FDTensor(FDTensor&& other)
|
||||
: buffer_(other.buffer_),
|
||||
shape(std::move(other.shape)),
|
||||
name(std::move(other.name)),
|
||||
dtype(other.dtype),
|
||||
external_data_ptr(other.external_data_ptr),
|
||||
device(other.device) {
|
||||
: buffer_(other.buffer_), shape(std::move(other.shape)),
|
||||
name(std::move(other.name)), dtype(other.dtype),
|
||||
external_data_ptr(other.external_data_ptr), device(other.device) {
|
||||
other.name = "";
|
||||
// Note(zhoushunjie): Avoid double free.
|
||||
other.buffer_ = nullptr;
|
||||
|
Reference in New Issue
Block a user