ONE - On-device Neural Engine
Loading...
Searching...
No Matches
FullyConnected.cpp
Go to the documentation of this file.
1/* Copyright (c) 2023 Samsung Electronics Co., Ltd. All Rights Reserved
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "luci_compute/Types.h"
18
19#include "ConvertTypes.h"
20#include "ConvertValues.h"
21
22#include <tensorflow/lite/kernels/internal/reference/fully_connected.h>
23
24#include <cassert>
25#include <cstdint>
26
27namespace luci
28{
29namespace compute
30{
31
32namespace
33{
34
35} // namespace
36
38{
39 if (_input_shape.rank() < 1 || _weights_shape.rank() != 2)
40 return false;
41
42 auto const input_elems = element_count(&_input_shape);
43 auto const weights_height = _weights_shape.dim(0).value();
44 auto const weights_width = _weights_shape.dim(1).value();
45 if (weights_height == 0 || weights_width == 0)
46 return false;
47 if (input_elems % weights_width != 0)
48 return false;
49 auto const batch_size = input_elems / weights_width;
50 auto const num_units = weights_height;
51 if (_bias_data)
52 {
53 if (element_count(&_bias_shape) != num_units)
54 return false;
55 }
56
57 get_act_minmax(_fused_act_func, _params.float_activation_min, _params.float_activation_max);
58
59 if (_keep_num_dims)
60 {
61 _output_shape.rank(_input_shape.rank());
62 for (uint32_t i = 0; i < _input_shape.rank(); i++)
63 _output_shape.dim(i) = _input_shape.dim(i);
64 _output_shape.dim(_input_shape.rank() - 1) = num_units;
65 }
66 else
67 {
68 _output_shape.rank(2);
69 _output_shape.dim(0) = batch_size;
70 _output_shape.dim(1) = num_units;
71 }
72
73 return true;
74}
75
77{
78 assert(_input_data != nullptr);
79 assert(_weights_data != nullptr);
80 // NOTE _bias_shape can be nullptr
81 assert(_output_data != nullptr);
82
83 // NOTE if this fails, structure may have changed
84 static_assert(sizeof(compute::FullyConnectedParams) == sizeof(tflite::FullyConnectedParams));
85
86 tflite::FullyConnectedParams params;
87
88 // clang-format off
101 // clang-format on
102
103 tflite::reference_ops::FullyConnected(
104 params, tflite_shape(_input_shape), _input_data, tflite_shape(_weights_shape), _weights_data,
105 tflite_shape(_bias_shape), _bias_data, tflite_shape(_output_shape), _output_data);
106}
107
108} // namespace compute
109} // namespace luci
uint32_t value(void) const
Return the value.
Definition Dimension.h:51
const Dimension & dim(uint32_t axis) const
Definition TensorShape.h:38
uint32_t rank(void) const
Definition TensorShape.h:35
FullyConnectedParams & params(void)
void get_act_minmax(const FusedActFunc act, float &act_min, float &act_max)
tflite::FullyConnectedWeightsFormat tflite_weights_format(const FullyConnectedWeightsFormat type)
tflite::RuntimeShape tflite_shape(const loco::TensorShape &shape)
FullyConnectedWeightsFormat weights_format
Definition Types.h:105