[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:
Jack Zhou
2022-11-23 11:34:02 +08:00
committed by GitHub
parent c11bfb8341
commit de98163efa
12 changed files with 1163 additions and 126 deletions

95
fastdeploy/core/fd_tensor.cc Executable file → Normal file
View 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;