Line data Source code
1 : // SPDX-License-Identifier: Apache-2.0
2 : /**
3 : * Copyright (C) 2025 SeungBaek Hong <sb92.hong@samsung.com>
4 : *
5 : * @file matmul_layer.cpp
6 : * @date 26 March 2025
7 : * @see https://github.com/nnstreamer/nntrainer
8 : * @author SeungBaek Hong <sb92.hong@samsung.com>
9 : * @bug No known bugs except for NYI items
10 : * @brief This is matrix multiplication layer class (operation layer)
11 : */
12 :
13 : #include "common_properties.h"
14 : #include <matmul_layer.h>
15 : #include <nntrainer_error.h>
16 : #include <nntrainer_log.h>
17 : #include <node_exporter.h>
18 : #include <util_func.h>
19 :
20 : #include <layer_context.h>
21 :
22 : namespace nntrainer {
23 :
24 12 : void MatMulLayer::finalize(InitLayerContext &context) {
25 12 : TensorDim inputDim0 = context.getInputDimensions()[0];
26 12 : TensorDim inputDim1 = context.getInputDimensions()[1];
27 :
28 12 : if (inputDim0[1] != inputDim1[1]) {
29 0 : throw std::invalid_argument("MatMulLayer requires matching channel size. ");
30 12 : } else if (inputDim0[3] != inputDim1[2]) {
31 : throw std::invalid_argument(
32 0 : "MatMulLayer requires matching inner dimensions. but got " +
33 0 : std::to_string(inputDim0[3]) + "!= " + std::to_string(inputDim1[2]));
34 : }
35 :
36 12 : TensorDim output_dim = TensorDim(inputDim0);
37 12 : output_dim.setTensorDim(3, inputDim1[3]);
38 12 : context.setOutputDimensions({std::move(output_dim)});
39 12 : }
40 :
41 6 : void MatMulLayer::forwarding_operation(const Tensor &input0,
42 : const Tensor &input1, Tensor &output) {
43 6 : input0.dot(input1, output);
44 6 : }
45 :
46 3 : void MatMulLayer::calcDerivative(RunLayerContext &context) {
47 3 : const Tensor &inDeriv = context.getIncomingDerivative(SINGLE_INOUT_IDX);
48 3 : Tensor &outDeriv0 = context.getOutgoingDerivative(0);
49 3 : Tensor &outDeriv1 = context.getOutgoingDerivative(1);
50 3 : const Tensor &input0 = context.getInput(0);
51 3 : const Tensor &input1 = context.getInput(1);
52 :
53 3 : inDeriv.dot(input1, outDeriv0, false, true);
54 3 : input0.dot(inDeriv, outDeriv1, true, false);
55 3 : }
56 :
57 88 : void MatMulLayer::setProperty(const std::vector<std::string> &values) {
58 88 : auto remain_props = loadProperties(values, matmul_props);
59 86 : if (!remain_props.empty()) {
60 : std::string msg = "[MatMulLayer] Unknown Layer Properties count " +
61 4 : std::to_string(values.size());
62 8 : throw exception::not_supported(msg);
63 : }
64 86 : }
65 :
66 : } /* namespace nntrainer */
|