tvm
Loading...
Searching...
No Matches
bnn.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
24#ifndef TVM_TOPI_NN_BNN_H_
25#define TVM_TOPI_NN_BNN_H_
26
27#include <tvm/sym/analyzer.h>
28#include <tvm/te/operation.h>
30#include <tvm/topi/tags.h>
31
32#include <string>
33
34namespace tvm {
35namespace topi {
36namespace nn {
37
38using namespace tvm::te;
39
51inline tvm::te::Tensor binarize_pack(const tvm::te::Tensor& data, int axis,
52 std::string name = "PackedInput",
53 std::string tag = "binarize_pack") {
54 auto ishape = data->shape;
55 TVM_FFI_ICHECK_EQ(GetConstInt(ishape[axis]) % 32, 0)
56 << "binarize_pack: axis size must be a multiple of 32";
57
58 sym::Analyzer analyzer;
59 auto n = ishape.size();
60 ffi::Array<PrimExpr> oshape;
61 for (size_t i = 0; i < n; ++i) {
62 oshape.push_back(i == static_cast<size_t>(axis) ? analyzer->Simplify(indexdiv(ishape[i], 32))
63 : ishape[i]);
64 }
65
66 return tvm::te::compute(
67 oshape,
68 [&](const ffi::Array<PrimVar>& indices) {
69 ffi::Array<PrimExpr> start_idx;
70 for (size_t i = 0; i < n; ++i) {
71 start_idx.push_back(i == static_cast<size_t>(axis) ? indices[i] * 32
72 : static_cast<PrimExpr>(indices[i]));
73 }
74 PrimExpr packed = IntImm(PrimType::UInt(32), 0);
75 for (size_t j = 0; j < 32; ++j) {
76 ffi::Array<PrimExpr> idx;
77 for (size_t i = 0; i < n; ++i) {
78 idx.push_back(i == static_cast<size_t>(axis) ? start_idx[i] + static_cast<int>(j)
79 : start_idx[i]);
80 }
81 auto sign = tvm::prim::cast(PrimType::UInt(32), data(idx) >= 0);
82 packed = (packed | sign);
83 if (j == 31) {
84 return packed;
85 }
86 packed = packed << 1;
87 }
88 return packed; // never reached, but suppress compiler warning
89 },
90 name, tag);
91}
92
102 using namespace tvm::prim;
103 TVM_FFI_ICHECK_EQ(data->shape.size(), 2) << "binary_dense requires 2-D data";
104 TVM_FFI_ICHECK_EQ(weight->shape.size(), 2) << "binary_dense requires 2-D weight";
105 TVM_FFI_ICHECK_EQ(data->dtype, PrimType::UInt(32)) << "binary_dense requires uint32 data";
106 TVM_FFI_ICHECK_EQ(weight->dtype, PrimType::UInt(32)) << "binary_dense requires uint32 weight";
107
108 auto batch = data->shape[0];
109 auto in_dim = data->shape[1];
110 auto out_dim = weight->shape[0];
111
112 auto k = tvm::te::reduce_axis(Range(0, in_dim), "k");
114 {batch, out_dim},
115 [&](PrimVar i, PrimVar j) {
116 return tvm::prim::sum(popcount(data(i, k) ^ weight(j, k)), {k});
117 },
118 "tensor", "binary_dense");
119
120 return tvm::te::compute(
121 {batch, out_dim}, [&](PrimVar i, PrimVar j) { return 32 * in_dim - 2.0f * matmul(i, j); },
122 "tensor", kElementWise);
123}
124
125} // namespace nn
126} // namespace topi
127} // namespace tvm
128#endif // TVM_TOPI_NN_BNN_H_
Algebra expression simplifications.
Managed reference class to IntImmNode.
Definition expr.h:152
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:447
static TVM_TIRX_DLL PrimType UInt(int bits, int lanes=1)
Construct an unsigned integer type with fixed lanes.
Checked scalar view over a VarNode.
Definition expr.h:742
Range container
Definition expr.h:1025
Managed reference to AnalyzerObj.
Definition analyzer.h:916
Tensor structure representing a possible input, or intermediate computation result.
Definition tensor.h:111
Utility functions for handling constants in TVM expressions.
Definition expr.h:47
PrimExpr sum(PrimExpr source, ffi::Array< s_tir::IterVar > axis, ffi::Array< PrimExpr > init={}, Location loc=UnknownLoc())
sum of source expression over axis
TVM_TIRX_DLL PrimExpr cast(PrimType t, PrimExpr value, Location loc=UnknownLoc())
cast value to type.
Tensor expression language DSL.
Definition extracted_task.h:33
IterVar reduce_axis(Range dom, std::string name="rv")
Create a new IterVar for reduction operations.
Tensor compute(ffi::Array< PrimExpr > shape, FCompute fcompute, std::string name="tensor", std::string tag="", ffi::Map< ffi::String, ffi::Any > attrs={})
Construct a new tensor by computing over shape, using the computation rule: result_tensor[axis] = fco...
tvm::te::Tensor binary_dense(const tvm::te::Tensor &data, const tvm::te::Tensor &weight)
Binary matrix multiplication using xor and bit-count.
Definition bnn.h:101
tvm::te::Tensor binarize_pack(const tvm::te::Tensor &data, int axis, std::string name="PackedInput", std::string tag="binarize_pack")
Binarization and bit-packing along a certain axis.
Definition bnn.h:51
constexpr auto kElementWise
Definition tags.h:32
tvm::te::Tensor matmul(const tvm::te::Tensor &A, const tvm::te::Tensor &B, bool trans_a=false, bool trans_b=false, std::string name="T_matmul", std::string tag=kMatMul)
Creates an operation that calculates a matrix multiplication (row-major notation): A(i,...
Definition transform.h:1638
Tensor sign(const Tensor &x, std::string name="T_sign", std::string tag=kElementWise)
Returns the sign of the tensor.
Definition elemwise.h:210
An object that builds and maintains block scope and StmtSref mapping for Dependence analysis.
Definition attr.h:23
TVM_TIRX_DLL PrimExpr indexdiv(PrimExpr a, PrimExpr b, Location loc=UnknownLoc())
compute floor(a / b) where a and b are non-negative.
Operation node can generate one or multiple Tensors.
Tag definitions.