• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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