1 | /* |
2 | * Copyright (c) Facebook, Inc. and its affiliates. |
3 | * All rights reserved. |
4 | * |
5 | * This source code is licensed under the BSD-style license found in the |
6 | * LICENSE file in the root directory of this source tree. |
7 | */ |
8 | |
9 | #include <assert.h> |
10 | #include <math.h> |
11 | #include <stddef.h> |
12 | #include <stdint.h> |
13 | #include <stdlib.h> |
14 | |
15 | #include <qnnpack.h> |
16 | #include <qnnpack/operator.h> |
17 | #include <qnnpack/log.h> |
18 | #include <qnnpack/params.h> |
19 | |
20 | |
21 | enum qnnp_status qnnp_create_channel_shuffle_nc_x8( |
22 | size_t groups, |
23 | size_t group_channels, |
24 | uint32_t flags, |
25 | qnnp_operator_t* channel_shuffle_out) |
26 | { |
27 | qnnp_operator_t channel_shuffle_op = NULL; |
28 | enum qnnp_status status = qnnp_status_uninitialized; |
29 | |
30 | if (!qnnp_params.initialized) { |
31 | qnnp_log_error("qnnp_create_channel_shuffle_nc_x8 failed because QNNPACK is not properly initialized" ); |
32 | goto error; |
33 | } |
34 | |
35 | status = qnnp_status_invalid_parameter; |
36 | |
37 | if (groups <= 1) { |
38 | qnnp_log_error( |
39 | "failed to create channel shuffle operator with %zu groups: " |
40 | "at least two groups required" , groups); |
41 | goto error; |
42 | } |
43 | |
44 | if (group_channels == 0) { |
45 | qnnp_log_error( |
46 | "failed to create channel shuffle operator with %zu group channels: " |
47 | "number of group channels must be non-zero" , group_channels); |
48 | goto error; |
49 | } |
50 | |
51 | status = qnnp_status_out_of_memory; |
52 | |
53 | channel_shuffle_op = calloc(1, sizeof(struct qnnp_operator)); |
54 | if (channel_shuffle_op == NULL) { |
55 | qnnp_log_error("failed to allocate %zu bytes for qnnp_operator structure" , sizeof(struct qnnp_operator)); |
56 | goto error; |
57 | } |
58 | |
59 | channel_shuffle_op->groups = groups; |
60 | channel_shuffle_op->group_channels = group_channels; |
61 | |
62 | channel_shuffle_op->ukernel_type = qnnp_ukernel_type_channel_shuffle; |
63 | channel_shuffle_op->format = qnnp_format_quint8; |
64 | |
65 | *channel_shuffle_out = channel_shuffle_op; |
66 | return qnnp_status_success; |
67 | |
68 | error: |
69 | qnnp_delete_operator(channel_shuffle_op); |
70 | return status; |
71 | } |
72 | |
73 | enum qnnp_status qnnp_setup_channel_shuffle_nc_x8( |
74 | qnnp_operator_t channel_shuffle_op, |
75 | size_t batch_size, |
76 | const uint8_t* input, |
77 | size_t input_stride, |
78 | uint8_t* output, |
79 | size_t output_stride) |
80 | { |
81 | if (!qnnp_params.initialized) { |
82 | qnnp_log_error("qnnp_setup_channel_shuffle_nc_x8 failed because QNNPACK is not properly initialized" ); |
83 | return qnnp_status_uninitialized; |
84 | } |
85 | |
86 | if (batch_size == 0) { |
87 | channel_shuffle_op->batch_size = 0; |
88 | return qnnp_status_success; |
89 | } |
90 | |
91 | channel_shuffle_op->batch_size = batch_size; |
92 | channel_shuffle_op->input = input; |
93 | channel_shuffle_op->input_pixel_stride = input_stride; |
94 | channel_shuffle_op->output = output; |
95 | channel_shuffle_op->output_pixel_stride = output_stride; |
96 | |
97 | return qnnp_status_success; |
98 | } |
99 | |