1 /**
2 * Copyright 2020 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "nnacl/fp32/crop_fp32.h"
17 #include <string.h>
18 #include "nnacl/op_base.h"
19 #include "nnacl/crop_parameter.h"
20
Pad4DOffset(const CropParameter * crop_param,int64_t * offset,int length)21 void Pad4DOffset(const CropParameter *crop_param, int64_t *offset, int length) {
22 int axis = crop_param->axis_;
23 for (int i = length - 1; i >= 0; --i) {
24 int offset_index = i - axis;
25 if (offset_index >= 0 && offset_index < COMM_SHAPE_SIZE) {
26 offset[i] = crop_param->offset_[offset_index];
27 } else {
28 offset[i] = 0;
29 }
30 }
31 }
32
Crop4D(const float * input,float * output,const int32_t * in_shape,const int32_t * out_shape,const CropParameter * crop_param,int thread_id,int thread_num)33 void Crop4D(const float *input, float *output, const int32_t *in_shape, const int32_t *out_shape,
34 const CropParameter *crop_param, int thread_id, int thread_num) {
35 int64_t offset_pad[DIMENSION_4D] = {0};
36 Pad4DOffset(crop_param, offset_pad, DIMENSION_4D);
37 int out_shape1 = out_shape[1];
38 int out_shape2 = out_shape[2];
39 int out_shape3 = out_shape[3];
40 size_t out_stride2 = out_shape3;
41 size_t out_stride1 = out_stride2 * out_shape2;
42 size_t out_stride0 = out_stride1 * out_shape1;
43 size_t in_stride2 = in_shape[3];
44 size_t in_stride1 = in_stride2 * in_shape[2];
45 size_t in_stride0 = in_stride1 * in_shape[1];
46 size_t copy_size = out_shape3 * sizeof(float);
47
48 size_t count_per_thread = UP_DIV(out_shape1, thread_num);
49 size_t thread_stride = thread_id * count_per_thread;
50 for (int i = 0; i < out_shape[0]; ++i) {
51 size_t out_offset0 = i * out_stride0;
52 size_t in_offset0 = (i + offset_pad[0]) * in_stride0 + offset_pad[3];
53 for (size_t j = 0; j < count_per_thread; ++j) {
54 size_t k = j + thread_stride;
55 if (k >= out_shape1) {
56 break;
57 }
58 size_t out_offset1 = k * out_stride1 + out_offset0;
59 size_t in_offset1 = (k + offset_pad[1]) * in_stride1 + in_offset0;
60 for (int l = 0; l < out_shape2; ++l) {
61 size_t out_offset = l * out_stride2 + out_offset1;
62 size_t in_offset = (l + offset_pad[2]) * in_stride2 + in_offset1;
63 memcpy(output + out_offset, input + in_offset, copy_size);
64 }
65 }
66 }
67 }
68
Crop4DNoParallel(const float * input,float * output,const int32_t * in_shape,const int32_t * out_shape,const CropParameter * crop_param)69 void Crop4DNoParallel(const float *input, float *output, const int32_t *in_shape, const int32_t *out_shape,
70 const CropParameter *crop_param) {
71 int64_t offset_pad[DIMENSION_4D] = {0};
72 Pad4DOffset(crop_param, offset_pad, DIMENSION_4D);
73 size_t in_dim2_stride = in_shape[3];
74 size_t in_dim1_stride = in_shape[2] * in_dim2_stride;
75 size_t in_dim0_stride = in_dim1_stride * in_shape[1];
76 size_t offset_3 = offset_pad[3];
77 size_t out_offset = 0;
78 size_t copy_num = out_shape[3];
79 size_t copy_size = copy_num * sizeof(float);
80 size_t in_dim0_end = offset_pad[0] + out_shape[0];
81 size_t in_dim1_end = offset_pad[1] + out_shape[1];
82 size_t in_dim2_end = offset_pad[2] + out_shape[2];
83 for (int i = offset_pad[0]; i < in_dim0_end; ++i) {
84 size_t dim0_offset = (size_t)i * in_dim0_stride + offset_3;
85 for (int j = offset_pad[1]; j < in_dim1_end; ++j) {
86 size_t dim1_offset = (size_t)j * in_dim1_stride + dim0_offset;
87 for (int k = offset_pad[2]; k < in_dim2_end; ++k) {
88 size_t in_offset = dim1_offset + (size_t)k * in_dim2_stride;
89 memcpy(output + out_offset, input + in_offset, copy_size);
90 out_offset += copy_num;
91 }
92 }
93 }
94 }
95