blob: bf5814d2ad4bf7896d0f9ab7e4cbbea446a3eb59 [file] [log] [blame]
telsoa014fcda012018-03-09 14:13:49 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
David Beckecb56cd2018-09-05 12:52:57 +01003// SPDX-License-Identifier: MIT
telsoa014fcda012018-03-09 14:13:49 +00004//
5
6#include "FullyConnected.hpp"
7
8#include <boost/assert.hpp>
9
10namespace armnn
11{
12
13void FullyConnected(const float* inputData,
14 float* outputData,
15 const TensorInfo& inputTensorInfo,
16 const TensorInfo& outputTensorInfo,
17 const float* weightData,
18 const float* biasData,
19 bool transposeWeights)
20{
telsoa01c577f2c2018-08-31 09:22:23 +010021 unsigned int N = outputTensorInfo.GetShape()[1]; // Outputs Vector Size.
telsoa014fcda012018-03-09 14:13:49 +000022
telsoa01c577f2c2018-08-31 09:22:23 +010023 BOOST_ASSERT(inputTensorInfo.GetNumDimensions() > 1); // Needs some data.
telsoa014fcda012018-03-09 14:13:49 +000024
telsoa01c577f2c2018-08-31 09:22:23 +010025 unsigned int K = 1; // Total number of activations in the input.
telsoa014fcda012018-03-09 14:13:49 +000026 for (unsigned int i = 1; i < inputTensorInfo.GetNumDimensions(); i++)
27 {
28 K *= inputTensorInfo.GetShape()[i];
29 }
30
31 for (unsigned int n = 0; n < inputTensorInfo.GetShape()[0]; n++)
32 {
33 for (unsigned int channelOutput = 0; channelOutput < N; channelOutput++)
34 {
35 float outval = 0.f;
36
37 for (unsigned int channelInput = 0; channelInput < K; channelInput++)
38 {
39 float weight;
40 if (transposeWeights)
41 {
42 weight = weightData[channelOutput * K + channelInput];
43 }
44 else
45 {
46 weight = weightData[channelInput * N + channelOutput];
47 }
48
49 outval += weight * inputData[n * K + channelInput];
50 }
51
52 if (biasData)
53 {
54 outval += biasData[channelOutput];
55 }
56
57 outputData[n * N + channelOutput] = outval;
58 }
59 }
60}
61
62} //namespace armnn