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
19
20enum qnnp_status qnnp_create_clamp_nc_u8(
21 size_t channels,
22 uint8_t output_min,
23 uint8_t output_max,
24 uint32_t flags,
25 qnnp_operator_t* clamp_out)
26{
27 qnnp_operator_t clamp_op = NULL;
28 enum qnnp_status status = qnnp_status_uninitialized;
29
30 if (!qnnp_params.initialized) {
31 qnnp_log_error("qnnp_create_clamp_nc_u8 failed because QNNPACK is not properly initialized");
32 goto error;
33 }
34
35 status = qnnp_status_invalid_parameter;
36
37 if (channels == 0) {
38 qnnp_log_error(
39 "failed to create Clamp operator with %zu channels: number of channels must be non-zero", channels);
40 goto error;
41 }
42
43 if (output_min > output_max) {
44 qnnp_log_error(
45 "failed to create Clamp operator with [%" PRIu8 ", %" PRIu8 "] output range: range min must be below range max",
46 output_min, output_max);
47 goto error;
48 }
49
50 status = qnnp_status_out_of_memory;
51
52 clamp_op = calloc(1, sizeof(struct qnnp_operator));
53 if (clamp_op == NULL) {
54 qnnp_log_error("failed to allocate %zu bytes for qnnp_operator structure", sizeof(struct qnnp_operator));
55 goto error;
56 }
57
58 clamp_op->channels = channels;
59 clamp_op->u8_clamping_params = qnnp_compute_u8_clamping_params(output_min, output_max);
60
61 clamp_op->ukernel_type = qnnp_ukernel_type_clamp;
62 clamp_op->format = qnnp_format_quint8;
63
64 *clamp_out = clamp_op;
65 return qnnp_status_success;
66
67error:
68 qnnp_delete_operator(clamp_op);
69 return status;
70}
71
72enum qnnp_status qnnp_setup_clamp_nc_u8(
73 qnnp_operator_t clamp,
74 size_t batch_size,
75 const uint8_t* input,
76 size_t input_stride,
77 uint8_t* output,
78 size_t output_stride)
79{
80 if (!qnnp_params.initialized) {
81 qnnp_log_error("qnnp_setup_clamp_nc_u8 failed because QNNPACK is not properly initialized");
82 return qnnp_status_uninitialized;
83 }
84
85 if (batch_size == 0) {
86 clamp->batch_size = 0;
87 return qnnp_status_success;
88 }
89
90 clamp->batch_size = batch_size;
91 clamp->input = input;
92 clamp->input_pixel_stride = input_stride;
93 clamp->output = output;
94 clamp->output_pixel_stride = output_stride;
95
96 return qnnp_status_success;
97}
98