mirror of
https://github.com/open-mmlab/mmdeploy.git
synced 2025-01-14 08:09:43 +08:00
* first * fix0 * fix1 * dirty work * wip * add allocator * finally done! * lint * fix lint * better gather * better onnx2ncnn * fix expand * [Fix] NCNN TensorSlice op bugs (#42) * fix custom ops support, fix multiple mark bug, add name mapping * check if the value_info need to be added * remove unnecessary print * add nms implement * two stage split wip * add two stage split * add split retinanet visualize * add two stage split (wip) * finish two stage split * fix lint * move parse string to mmdeploy.utils * add calib data generator * create calib dataset * finish end2end int8 * add split two stage tensorrt visualize * fix tensorslice bugs * fix lint * fix clang-format * remove comments * int param * fix lint Co-authored-by: grimoire <yaoqian@sensetime.com> * add two stage ncnn support * remove unused ops * git unused config * remove no_grad, should add in refactor * add ncnn wrapper * fix lint * size return tuple * Resolve grammar error * Fix lint * Trim Trailing Whitespace * fix trim * update wrapper * remove logs * remove * csrc optimize Co-authored-by: hanrui1sensetime <83800577+hanrui1sensetime@users.noreply.github.com>
199 lines
5.5 KiB
C++
199 lines
5.5 KiB
C++
#include "tensorslice.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include "../ncnn_ops_definer.h"
|
|
|
|
namespace mmlab {
|
|
using namespace ncnn;
|
|
DEFINE_LAYER_CREATOR(TensorSlice)
|
|
DEFINE_NCNN_OPS(TensorSlice, TensorSlice)
|
|
TensorSlice::TensorSlice() {
|
|
one_blob_only = true;
|
|
support_inplace = false;
|
|
}
|
|
|
|
int TensorSlice::load_param(const ParamDict& pd) {
|
|
starts = pd.get(0, Mat());
|
|
ends = pd.get(1, Mat());
|
|
axes = pd.get(2, Mat());
|
|
steps = pd.get(3, Mat());
|
|
if (axes.w == 0) {
|
|
axes.create(starts.w);
|
|
int* axes_ptr = axes;
|
|
for (int i = 0; i < starts.w; i++) {
|
|
axes_ptr[i] = i;
|
|
}
|
|
}
|
|
if (steps.w == 0) {
|
|
steps.create(axes.w);
|
|
steps.fill(1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static inline int get_shape_by_axes(const Mat& blob, int axes, int dims) {
|
|
switch (dims - axes) {
|
|
case 0:
|
|
return blob.w;
|
|
case 1:
|
|
return blob.h;
|
|
case 2:
|
|
return blob.c;
|
|
default:
|
|
fprintf(stderr, "wrong axes %d!\n", axes);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int TensorSlice::forward(const Mat& bottom_blob, Mat& top_blob,
|
|
const Option& opt) const {
|
|
int dims = bottom_blob.dims;
|
|
size_t elemsize = bottom_blob.elemsize;
|
|
const int* start_ptr = starts;
|
|
const int* end_ptr = ends;
|
|
const float* axes_ptr = axes;
|
|
const int* step_ptr = steps;
|
|
if (starts.w > dims || ends.w > dims) {
|
|
fprintf(stderr, "start/end attributes shape error!\n");
|
|
return -100;
|
|
}
|
|
if (dims == 1) {
|
|
for (int i = 0; i < axes.w; i++) {
|
|
int positive_axis = axes_ptr[i] < 0 ? dims + axes_ptr[i] : axes_ptr[i];
|
|
int step = step_ptr[i];
|
|
std::vector<float> temp_val;
|
|
int start = start_ptr[i];
|
|
int end = end_ptr[i];
|
|
int cur = start;
|
|
if (step > 0) {
|
|
while (cur < end && cur < bottom_blob.w) {
|
|
temp_val.push_back(bottom_blob[cur]);
|
|
cur += step;
|
|
}
|
|
} else if (step < 0) {
|
|
while (cur > end && cur > 0) {
|
|
temp_val.push_back(bottom_blob[cur]);
|
|
cur += step;
|
|
}
|
|
} else {
|
|
fprintf(stderr, "step should not be 0!\n");
|
|
return -100;
|
|
}
|
|
top_blob.create(temp_val.size(), elemsize, opt.blob_allocator);
|
|
for (int i = 0; i < temp_val.size(); i++) {
|
|
top_blob[i] = temp_val[i];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
if (dims == 2) {
|
|
std::vector<std::vector<int> > active_indice;
|
|
std::vector<int> indices;
|
|
for (int i = 0; i < bottom_blob.h; i++) {
|
|
indices.push_back(i);
|
|
}
|
|
active_indice.push_back(indices);
|
|
indices.clear();
|
|
for (int i = 0; i < bottom_blob.w; i++) {
|
|
indices.push_back(i);
|
|
}
|
|
active_indice.push_back(indices);
|
|
for (int i = 0; i < axes.w; i++) {
|
|
int positive_axis = axes_ptr[i] < 0 ? dims + axes_ptr[i] : axes_ptr[i];
|
|
int step = step_ptr[i];
|
|
int start = start_ptr[i];
|
|
int end = end_ptr[i];
|
|
int dim_shape = get_shape_by_axes(bottom_blob, positive_axis, dims);
|
|
if (dim_shape < 0) {
|
|
return -1;
|
|
}
|
|
end = end < dim_shape ? end : dim_shape;
|
|
int cur = start;
|
|
std::vector<int> temp_indice;
|
|
if (step > 0) {
|
|
while (cur < end && cur < dim_shape) {
|
|
temp_indice.push_back(cur);
|
|
cur += step;
|
|
}
|
|
} else if (step < 0) {
|
|
while (cur > end && cur > 0) {
|
|
temp_indice.push_back(cur);
|
|
cur += step;
|
|
}
|
|
} else {
|
|
fprintf(stderr, "step should not be 0!\n");
|
|
return -100;
|
|
}
|
|
active_indice[positive_axis - 1] = temp_indice;
|
|
}
|
|
top_blob.create((int)active_indice[1].size(), (int)active_indice[0].size(),
|
|
elemsize, opt.blob_allocator);
|
|
for (int i = 0; i < active_indice[0].size(); i++) {
|
|
for (int j = 0; j < active_indice[1].size(); j++) {
|
|
top_blob.row(i)[j] =
|
|
bottom_blob.row(active_indice[0][i])[active_indice[1][j]];
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
if (dims == 3) {
|
|
std::vector<std::vector<int> > active_indice;
|
|
std::vector<int> indices;
|
|
for (int i = 0; i < bottom_blob.c; i++) {
|
|
indices.push_back(i);
|
|
}
|
|
active_indice.push_back(indices);
|
|
indices.clear();
|
|
for (int i = 0; i < bottom_blob.h; i++) {
|
|
indices.push_back(i);
|
|
}
|
|
active_indice.push_back(indices);
|
|
indices.clear();
|
|
for (int i = 0; i < bottom_blob.w; i++) {
|
|
indices.push_back(i);
|
|
}
|
|
active_indice.push_back(indices);
|
|
for (int i = 0; i < axes.w; i++) {
|
|
int positive_axis = axes_ptr[i] < 0 ? dims + axes_ptr[i] : axes_ptr[i];
|
|
int step = step_ptr[i];
|
|
|
|
int start = start_ptr[i];
|
|
int end = end_ptr[i];
|
|
int cur = start;
|
|
std::vector<int> temp_indice;
|
|
if (step > 0) {
|
|
while (cur < end && cur < bottom_blob.w) {
|
|
temp_indice.push_back(cur);
|
|
cur += step;
|
|
}
|
|
} else if (step < 0) {
|
|
while (cur > end && cur > 0) {
|
|
temp_indice.push_back(cur);
|
|
cur += step;
|
|
}
|
|
} else {
|
|
fprintf(stderr, "step should not be 0!\n");
|
|
return -100;
|
|
}
|
|
active_indice[positive_axis] = temp_indice;
|
|
}
|
|
top_blob.create((int)active_indice[2].size(), (int)active_indice[1].size(),
|
|
(int)active_indice[0].size(), elemsize, opt.blob_allocator);
|
|
for (int i = 0; i < active_indice[0].size(); i++) {
|
|
for (int j = 0; j < active_indice[1].size(); j++) {
|
|
for (int k = 0; k < active_indice[2].size(); k++) {
|
|
top_blob.channel(i).row(j)[k] =
|
|
bottom_blob.channel(active_indice[0][i])
|
|
.row(active_indice[1][j])[active_indice[2][k]];
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
} // namespace mmlab
|