blob: 6d4fff261874455f9f6cfd8a394438210d9de3d5 [file] [log] [blame]
Jared Duke13689fe2019-04-16 16:22:07 -04001/* Copyright 2019 Google LLC. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14==============================================================================*/
15
Alex Stark8221a672019-08-07 17:41:19 -040016#include <cstdint>
Benoit Jacoba0ba3ac2019-04-08 12:00:37 -040017#include <iostream>
18
Benoit Jacobf7ea5832020-03-27 21:58:51 -040019#include "ruy/ruy.h"
Benoit Jacoba0ba3ac2019-04-08 12:00:37 -040020
Benoit Jacobf5b81082019-04-11 15:59:22 -040021void ExampleMulFloat(ruy::Context *context) {
22 const float lhs_data[] = {1, 2, 3, 4};
23 const float rhs_data[] = {1, 2, 3, 4};
24 float dst_data[4];
25
26 ruy::Matrix<float> lhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070027 ruy::MakeSimpleLayout(2, 2, ruy::Order::kRowMajor, lhs.mutable_layout());
28 lhs.set_data(lhs_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -040029 ruy::Matrix<float> rhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070030 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, rhs.mutable_layout());
31 rhs.set_data(rhs_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -040032 ruy::Matrix<float> dst;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070033 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, dst.mutable_layout());
34 dst.set_data(dst_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -040035
Benoit Jacob9f53ba42020-04-16 11:59:51 -070036 ruy::MulParams<float, float> mul_params;
Benoit Jacobfb8fa3b2020-06-18 13:08:23 -070037 ruy::Mul(lhs, rhs, mul_params, context, &dst);
Benoit Jacobf5b81082019-04-11 15:59:22 -040038
39 std::cout << "Example Mul, float:\n";
40 std::cout << "LHS:\n" << lhs;
41 std::cout << "RHS:\n" << rhs;
42 std::cout << "Result:\n" << dst << "\n";
43}
44
45void ExampleMulFloatWithBiasAddAndClamp(ruy::Context *context) {
46 const float lhs_data[] = {1, 2, 3, 4};
47 const float rhs_data[] = {1, 2, 3, 4};
48 const float bias_data[] = {1, 0};
49 float dst_data[4];
50
51 ruy::Matrix<float> lhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070052 ruy::MakeSimpleLayout(2, 2, ruy::Order::kRowMajor, lhs.mutable_layout());
53 lhs.set_data(lhs_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -040054 ruy::Matrix<float> rhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070055 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, rhs.mutable_layout());
56 rhs.set_data(rhs_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -040057 ruy::Matrix<float> dst;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070058 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, dst.mutable_layout());
59 dst.set_data(dst_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -040060
Benoit Jacob9f53ba42020-04-16 11:59:51 -070061 ruy::MulParams<float, float> mul_params;
Benoit Jacobe866a682020-04-22 11:04:33 -070062 mul_params.set_bias(bias_data);
63 mul_params.set_clamp_min(0);
64 mul_params.set_clamp_max(15);
Benoit Jacobfb8fa3b2020-06-18 13:08:23 -070065 ruy::Mul(lhs, rhs, mul_params, context, &dst);
Benoit Jacobf5b81082019-04-11 15:59:22 -040066
67 std::cout << "Example Mul, float with bias addition and clamp:\n";
68 std::cout << "LHS:\n" << lhs;
69 std::cout << "RHS:\n" << rhs;
70 std::cout << "Result:\n" << dst << "\n";
71}
72
Benoit Jacobe91fa442019-05-29 15:15:44 -040073void ExampleMulUint8AsymmetricQuantized(ruy::Context *context) {
74 const std::uint8_t lhs_data[] = {124, 125, 126, 127};
75 const std::uint8_t rhs_data[] = {129, 130, 131, 132};
Benoit Jacobf5b81082019-04-11 15:59:22 -040076 std::uint8_t dst_data[4];
77
78 ruy::Matrix<std::uint8_t> lhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070079 ruy::MakeSimpleLayout(2, 2, ruy::Order::kRowMajor, lhs.mutable_layout());
80 lhs.set_data(lhs_data);
81 lhs.set_zero_point(125);
Benoit Jacobf5b81082019-04-11 15:59:22 -040082 ruy::Matrix<std::uint8_t> rhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070083 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, rhs.mutable_layout());
84 rhs.set_data(rhs_data);
85 rhs.set_zero_point(132);
Benoit Jacobf5b81082019-04-11 15:59:22 -040086 ruy::Matrix<std::uint8_t> dst;
Benoit Jacob2bfeb072020-04-22 10:55:54 -070087 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, dst.mutable_layout());
88 dst.set_data(dst_data);
89 dst.set_zero_point(129);
Benoit Jacobf5b81082019-04-11 15:59:22 -040090
Benoit Jacob9f53ba42020-04-16 11:59:51 -070091 ruy::MulParams<std::int32_t, std::uint8_t> mul_params;
Benoit Jacobe866a682020-04-22 11:04:33 -070092 mul_params.set_multiplier_fixedpoint(1 << 30);
Benoit Jacobd1a14aa2020-01-14 13:28:47 -050093
Benoit Jacobe866a682020-04-22 11:04:33 -070094 mul_params.set_multiplier_exponent(0);
Benoit Jacobfb8fa3b2020-06-18 13:08:23 -070095 ruy::Mul(lhs, rhs, mul_params, context, &dst);
Benoit Jacobf5b81082019-04-11 15:59:22 -040096
Benoit Jacobe91fa442019-05-29 15:15:44 -040097 std::cout << "Example Mul, uint8 quantized with asymmetric zero points:\n";
Benoit Jacobf5b81082019-04-11 15:59:22 -040098 std::cout << "LHS:\n" << lhs;
99 std::cout << "RHS:\n" << rhs;
100 std::cout << "Result:\n" << dst << "\n";
101}
Benoit Jacobf5b81082019-04-11 15:59:22 -0400102void ExampleMulInt8PerChannelQuantized(ruy::Context *context) {
103 const std::int8_t lhs_data[] = {1, 2, 3, 4};
104 const std::int8_t rhs_data[] = {1, 2, 3, 4};
105 const std::int32_t multiplier_data[] = {3 << 28, 5 << 28};
106 const int exponent_data[] = {1, -2};
107 std::int8_t dst_data[4];
108
109 ruy::Matrix<std::int8_t> lhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -0700110 ruy::MakeSimpleLayout(2, 2, ruy::Order::kRowMajor, lhs.mutable_layout());
111 lhs.set_data(lhs_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -0400112 ruy::Matrix<std::int8_t> rhs;
Benoit Jacob2bfeb072020-04-22 10:55:54 -0700113 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, rhs.mutable_layout());
114 rhs.set_data(rhs_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -0400115 ruy::Matrix<std::int8_t> dst;
Benoit Jacob2bfeb072020-04-22 10:55:54 -0700116 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, dst.mutable_layout());
117 dst.set_data(dst_data);
Benoit Jacobf5b81082019-04-11 15:59:22 -0400118
Benoit Jacob9f53ba42020-04-16 11:59:51 -0700119 ruy::MulParams<std::int32_t, std::int8_t> mul_params;
Benoit Jacobe866a682020-04-22 11:04:33 -0700120 mul_params.set_multiplier_fixedpoint_perchannel(multiplier_data);
121 mul_params.set_multiplier_exponent_perchannel(exponent_data);
Benoit Jacobfb8fa3b2020-06-18 13:08:23 -0700122 ruy::Mul(lhs, rhs, mul_params, context, &dst);
Benoit Jacobf5b81082019-04-11 15:59:22 -0400123
124 std::cout << "Example Mul, int8 quantized with per-channel multipliers\n";
125 std::cout << "LHS:\n" << lhs;
126 std::cout << "RHS:\n" << rhs;
127 std::cout << "Result:\n" << dst << "\n";
128}
Benoit Jacob5f40d622021-10-20 20:12:18 -0700129
Benoit Jacob87828362020-12-21 13:53:34 -0800130void ExampleMulInt8GetRawAccumulators(ruy::Context *context) {
Benoit Jacob177062d2020-12-21 12:39:19 -0800131 const std::int8_t lhs_data[] = {1, 2, 3, 4};
132 const std::int8_t rhs_data[] = {1, 2, 3, 4};
133 std::int32_t dst_data[4];
134
135 ruy::Matrix<std::int8_t> lhs;
136 ruy::MakeSimpleLayout(2, 2, ruy::Order::kRowMajor, lhs.mutable_layout());
137 lhs.set_data(lhs_data);
138 ruy::Matrix<std::int8_t> rhs;
139 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, rhs.mutable_layout());
140 rhs.set_data(rhs_data);
141 ruy::Matrix<std::int32_t> dst;
142 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, dst.mutable_layout());
143 dst.set_data(dst_data);
144
145 // When Dst is int32, mul_params is unused.
146 ruy::MulParams<std::int32_t, std::int32_t> mul_params;
147 ruy::Mul(lhs, rhs, mul_params, context, &dst);
148
Benoit Jacob87828362020-12-21 13:53:34 -0800149 std::cout << "Example Mul, returning raw int32 accumulators:\n";
Benoit Jacob177062d2020-12-21 12:39:19 -0800150 std::cout << "LHS:\n" << lhs;
151 std::cout << "RHS:\n" << rhs;
152 std::cout << "Result:\n" << dst << "\n";
153}
Benoit Jacobf5b81082019-04-11 15:59:22 -0400154
Benoit Jacob5f40d622021-10-20 20:12:18 -0700155void ExampleMulInt8TimesInt16PerChannelQuantized(ruy::Context *context) {
156 const std::int8_t lhs_data[] = {1, 2, 3, 4};
157 const std::int16_t rhs_data[] = {1000, 2000, 3000, 4000};
158 const std::int32_t multiplier_data[] = {3 << 28, 5 << 28};
159 const int exponent_data[] = {1, -2};
160 std::int16_t dst_data[4];
161
162 ruy::Matrix<std::int8_t> lhs;
163 ruy::MakeSimpleLayout(2, 2, ruy::Order::kRowMajor, lhs.mutable_layout());
164 lhs.set_data(lhs_data);
165 ruy::Matrix<std::int16_t> rhs;
166 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, rhs.mutable_layout());
167 rhs.set_data(rhs_data);
168 ruy::Matrix<std::int16_t> dst;
169 ruy::MakeSimpleLayout(2, 2, ruy::Order::kColMajor, dst.mutable_layout());
170 dst.set_data(dst_data);
171
172 ruy::MulParams<std::int32_t, std::int16_t> mul_params;
173 mul_params.set_multiplier_fixedpoint_perchannel(multiplier_data);
174 mul_params.set_multiplier_exponent_perchannel(exponent_data);
175 ruy::Mul(lhs, rhs, mul_params, context, &dst);
176
177 std::cout << "Example Mul, int8 times int16 quantized with per-channel "
178 "multipliers\n";
179 std::cout << "LHS:\n" << lhs;
180 std::cout << "RHS:\n" << rhs;
181 std::cout << "Result:\n" << dst << "\n";
182}
183
Benoit Jacoba0ba3ac2019-04-08 12:00:37 -0400184int main() {
185 ruy::Context context;
Benoit Jacobf5b81082019-04-11 15:59:22 -0400186 ExampleMulFloat(&context);
187 ExampleMulFloatWithBiasAddAndClamp(&context);
Benoit Jacobe91fa442019-05-29 15:15:44 -0400188 ExampleMulUint8AsymmetricQuantized(&context);
Benoit Jacobf5b81082019-04-11 15:59:22 -0400189 ExampleMulInt8PerChannelQuantized(&context);
Benoit Jacob87828362020-12-21 13:53:34 -0800190 ExampleMulInt8GetRawAccumulators(&context);
Benoit Jacob5f40d622021-10-20 20:12:18 -0700191 ExampleMulInt8TimesInt16PerChannelQuantized(&context);
Benoit Jacoba0ba3ac2019-04-08 12:00:37 -0400192}