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/arith/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
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 }
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::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 TVM_FFI_ICHECK_EQ(data->shape.size(), 2) << "binary_dense requires 2-D data";
103 TVM_FFI_ICHECK_EQ(weight->shape.size(), 2) << "binary_dense requires 2-D weight";
104 TVM_FFI_ICHECK_EQ(data->dtype, PrimType::UInt(32)) << "binary_dense requires uint32 data";
105 TVM_FFI_ICHECK_EQ(weight->dtype, PrimType::UInt(32)) << "binary_dense requires uint32 weight";
106
107 auto batch = data->shape[0];
108 auto in_dim = data->shape[1];
109 auto out_dim = weight->shape[0];
110
111 auto k = tvm::te::reduce_axis(Range(0, in_dim), "k");
113 {batch, out_dim},
114 [&](PrimVar i, PrimVar j) { return tvm::sum(popcount(data(i, k) ^ weight(j, k)), {k}); },
115 "tensor", "binary_dense");
116
117 return tvm::te::compute(
118 {batch, out_dim}, [&](PrimVar i, PrimVar j) { return 32 * in_dim - 2.0f * matmul(i, j); },
119 "tensor", kElementWise);
120}
121
122} // namespace nn
123} // namespace topi
124} // namespace tvm
125#endif // TVM_TOPI_NN_BNN_H_
Algebra expression simplifications.
Managed reference class to IntImmNode.
Definition expr.h:504
Typed reference/view over any Expr whose ExprNode::ty is PrimType.
Definition base_expr.h:401
static PrimType UInt(int bits, int lanes=1)
Construct an unsigned integer type with fixed lanes.
Range container
Definition expr.h:610
RAII wrapper function to enter and exit a context object similar to python's with syntax.
Definition with_context.h:59
Managed reference to AnalyzerObj.
Definition analyzer.h:931
Tensor structure representing a possible input, or intermediate computation result.
Definition tensor.h:98
Checked scalar view over a VarNode.
Definition var.h:46
Utility functions for handling constants in TVM expressions.
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:1636
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 analyzer.h:40
PrimExpr cast(PrimType t, PrimExpr value, Span span=Span())
cast value to type.
PrimExpr indexdiv(PrimExpr a, PrimExpr b, Span span=Span())
compute floor(a / b) where a and b are non-negative.
PrimExpr sum(PrimExpr source, ffi::Array< tirx::IterVar > axis, ffi::Array< PrimExpr > init={}, Span span=Span())
sum of source expression over axis
PrimExpr popcount(PrimExpr x, Span span=Span())
Definition op.h:764
Operation node can generate one or multiple Tensors.
Tag definitions.