Canvas: End-to-End Kernel Architecture Search in Neural Networks
The demands for higher performance and accuracy in neural networks (NNs)
never end. Existing tensor compilation and Neural Architecture Search (NAS)
techniques orthogonally optimize the two goals but actually share many
similarities in their concrete strategies. We exploit such opportunities by
combining the two into one and make a case for Kernel Architecture Search
(KAS). KAS reviews NAS from a system perspective and zooms into a more
fine-grained level to generate neural kernels with both high performance and
good accuracy. To demonstrate the potential of KAS, we build an end-to-end
framework, Canvas, to find high-quality kernels as convolution replacements.
Canvas samples from a rich set of fine-grained primitives to stochastically and
iteratively construct new kernels and evaluate them according to user-specified
constraints. Canvas supports freely adjustable tensor dimension sizes inside
the kernel and uses two levels of solvers to satisfy structural legality and
fully utilize model budgets. The evaluation shows that by replacing standard
convolutions with generated new kernels in common NNs, Canvas achieves average
1.5x speedups compared to the previous state-of-the-art with acceptable
accuracy loss and search efficiency. Canvas verifies the practicability of KAS
by rediscovering many manually designed kernels in the past and producing new
structures that may inspire future machine learning innovations. For source
code and implementation, we open-sourced Canvas at
https://github.com/tsinghua-ideal/Canvas.
Chenggang Zhao, Genghan Zhang, Mingyu Gao
# Canvas: End-to-End Kernel Architecture Search in Neural Networks

###### Abstract

The demands for higher performance and accuracy in neural networks (NNs) never end. Existing tensor compilation and Neural Architecture Search (NAS) techniques orthogonally optimize the two goals but actually share many similarities in their concrete strategies. We exploit such opportunities by combining the two into one and make a case for Kernel Architecture Search (KAS). KAS reviews NAS from a system perspective and zooms into a more fine-grained level to generate neural kernels with both high performance and good accuracy. To demonstrate the potential of KAS, we build an end-to-end framework, Canvas, to find high-quality kernels as convolution replacements. Canvas samples from a rich set of fine-grained primitives to stochastically and iteratively construct new kernels and evaluate them according to user-specified constraints. Canvas supports freely adjustable tensor dimension sizes inside the kernel and uses two levels of solvers to satisfy structural legality and fully utilize model budgets. The evaluation shows that by replacing standard convolutions with generated new kernels in common NNs, Canvas achieves average \(1.5\times\) speedups compared to the previous state-of-the-art with acceptable accuracy loss and search efficiency. Canvas verifies the practicability of KAS by rediscovering many manually designed kernels in the past and producing new structures that may inspire future machine learning innovations. For source code and implementation, we open-sourced Canvas at [https://github.com/tsinghua-ideal/Canvas](https://github.com/tsinghua-ideal/Canvas).

Machine Learning Tensor Compilers Neural Architecture Search

## 1 Introduction

Many emerging techniques backed by neural networks (NNs), including computer vision, natural language processing, and robotics, have boomed these years and made tremendous progress. However, NNs remain as a complex algorithm that not only consumes significant computation resources to achieve acceptable (e.g., real-time) performance but also lacks an effective and theoretical methodology to design models with high accuracy. The demands for high performance and high accuracy only keep increasing when NNs are applied to more scenarios in the real world.

System and machine learning communities have adopted orthogonal approaches to satisfy the high demands above. From a system perspective, NNs are represented as tensor programs, and specialized tensor compilers and frameworks have been developed to realize high-performance execution on different hardware platforms. On the other hand, NN algorithm researchers have started to use automatic methods to design better model architectures with improved accuracy, known as Neural Architecture Search (NAS). Despite the different goals, these two directions share many common underlying techniques. Both attempt to reorganize the NN structures and redistribute the computations by transforming
their basic blocks in the rich design spaces; both require timely evaluation as the feedback to guide the exploration. Consequently, recent efforts have started to exploit these similarities and simultaneously conduct performance and accuracy exploration with a careful tradeoff between the two. Examples include giving up mathematical equivalence in tensor compilers to unleash higher performance [1, 2], and making NAS aware of performance besides the accuracy goal [3, 4, 5, 6].

In this paper, we take these opportunities one step further and make a case for a new paradigm of _Kernel Architecture Search_ (KAS). To maximize runtime performance while pursuing high model accuracy, KAS searches for an efficient _kernel architecture_ from a lower-level system perspective. It then uses the generated kernels to replace the standard layers (e.g., convolutions) in existing NNs. KAS _stochastically and iteratively_ builds candidate kernels using a rich set of _fine-grained primitives_. It treats _runtime performance as first-priority constraints_ and searches for kernels that achieve the best accuracy within the given performance limit. By completely discarding mathematical equivalence and searching for new designs, KAS enables higher performance than tensor compilers. By primarily focusing on runtime and composing kernels in a fine-grained way, KAS complements NAS from a system perspective while retaining similar levels of accuracy.

To demonstrate the promising potentials of KAS, we further build an end-to-end, automated, and efficient framework, Canvas, that could find new high-quality kernels to replace traditional convolutions. Canvas relies on a **fine-grained primitive library** as the building blocks for kernel construction, following the philosophy of _decoupling data rearrangements and arithmetic computations_, The primitive designs are inspired by the decoupling concept in system research while at the same time also having great expressibility to realize complicated mathematical compositions in machine learning. From such a primitive library, Canvas uses a **random sampler** to _stochastically and iteratively generate candidate kernels_ from a large search space. The sampler carefully adjusts the sampling probabilities of different primitive types to ensure fair and legitimate kernel construction. It also applies various pruning rules. Then Canvas evaluates the candidate kernels using two classes of **user-specified constraints and optimization goals**, including those that can be _analytically_ modeled and calculated (e.g., numbers of operations and parameters), and those that need _experimental_ measurements (e.g., runtime and accuracy). Finally, a key innovation of Canvas is the use of free _dynamic variables_ on tensor dimension sizes during kernel generation. Dynamic variables greatly enrich the search space but must eventually be substituted with reasonable values that satisfy all structural legality and fully utilize allowed model budgets. So we design **two levels of dynamic variable solvers** in Canvas to handle the two requirements with provable correctness and high efficiency.

On top of several popular backbone NNs, we use Canvas to search for the best kernels to replace standard convolutions. Compared with the original model optimized by TVM Ansor [7], Canvas achieves on average \(1.5\times\) and up to \(4.6\times\) speedups with acceptable accuracy loss (\(\sim 1\%\)). And models are reduced to \(0.1\sim 0.6\times\) of the original sizes. Canvas also outperforms a previous work that searches for efficient kernel implementations in a network-independent way and then applies manual layer-wise optimizations [2], by \(1.4\sim 1.6\times\) faster. We also conduct detailed case studies to examine what kinds of kernels Canvas discovers. Interestingly, Canvas rediscovers many manually proposed kernel designs in the past and produces previously unexplored structures that may inspire future NN design automation and innovations.

## 2 Background

To continuously improve the efficiency and effectiveness of neural networks (NNs), the two research communities of computer systems and machine learning have taken different but complementary approaches in the past years. From the system perspective, there is a large design space about how to carry out the computations specified by the mathematical representation of an NN, resulting in potential orders of magnitude runtime performance differences on real hardware platforms like CPUs, GPUs, and specialized chips. To ease the efforts of programming and optimization, many frameworks, including PyTorch [8], TensorFlow [9], and TVM [10, 11], have been proposed. They typically represent NNs as _tensor programs_ and apply fine-grained optimizations at multiple levels, from the computation graph [12, 13, 1, 14] to the loop nest of an individual operator kernel [10, 7].

Meanwhile, _Neural Architecture Search_ (NAS) has become an increasingly popular methodology for designing effective NN architectures. Indeed, a large part of the recently proposed state-of-the-art NNs is automatically discovered by NAS rather than composed manually [15, 16, 17, 18]. NAS typically defines a highly modular search space by dividing the backbone network topology into basic units or cells of various sizes. Then it searches for how to build each cell by connecting basic layers like convolution and pooling. During the search, the accuracy levels of the candidate cell structures are continuously evaluated using statistic metrics or through training sample datasets. In some sense, NAS also organizes NNs towards a better evaluation objective, but rather on model accuracy than runtime performance.
Regardless of the research perspectives, the essence of the problem lies in getting reliable accuracy levels with a demand for less computation. It is only the overall research context that leads to the two communities of systems and machine learning focusing on different approaches: the system side leverages fine-grained performance optimizations under the rigid constraint of mathematical equivalence; in contrast, the ML side is free to transform the mathematical form of the NN at a coarse-grained level (i.e., layer-wise operators) to improve accuracy.

Turner et al. [2] first captured this new opportunity. Specifically, they introduced two NAS-style transformations into the current TVM [10] compilation framework: bottlenecking (reducing channel counts) and grouping (dividing channels into groups). The new transformations gave up traditional compiler transformation equivalence. However, this work was still preliminary, as it only changed the loop ranges while retaining the original loop structure of traditional convolutions, leaving abundant opportunities unexplored. Also, the workflow was not end-to-end and required manual post-search fine-tuning. Therefore, in this work, we attempt to comprehensively study this new direction by searching for novel neural structures from a larger design space and a finer granularity without the limitation of transformation equivalence and achieve a user-friendly end-to-end system.

## 3 Kernel Architecture Search

The similarity between tensor program optimizations and NAS techniques motivates us to take one step further along the path. Specifically, we propose _Kernel Architecture Search_ (KAS). KAS is a new paradigm to construct effective and efficient tensor computation kernels, the basic building blocks in NNs. The main innovation of KAS is to _use system techniques to search for novel kernel designs with high accuracy and high performance_. We view it as neither a compiler nor a pruner/tuner but an automated explorer for new kernels. This is because we are not transforming existing kernels but constructing new kernels from scratch. In the long term, we aim at automatic algorithmic exploration from the system perspective under the concept of KAS.

KAS treats the computation of a kernel as a micro directed acyclic graph (micro-DAG) \(G=(V,E)\). Each node \(v_{i}\in V\) represents the current tensor shape, and edge \(e_{ij}\in E\) represents a fine-grained primitive that transforms tensor \(v_{i}\) to the output tensor \(v_{j}\). Fine-grained primitives offer a lower-level representation than traditional coarse-grained kernels like convolutions and matrix/tensor multiplications. They enable us to replace the monolithic and heavy kernel into a DAG of cheap primitives with a smaller total cost.

In KAS, we apply a new perspective to balance performance and accuracy by _treating runtime performance as first-priority constraints_ and searching for kernels that achieve the best accuracy within the given performance limit. Such a "performance-first" philosophy essentially flips the conventional workflow, which first designs NN models with certain accuracy levels and then uses tensor compilers to optimize performance. The new approach allows us to balance the two objectives better with a smoother flow in our system.

**Design challenges.** Nevertheless, realizing a practical KAS framework to automatically and efficiently explore the huge design space is still challenging. We summarize the key questions below, which our proposed system has to address.

Figure 1: System overview of Canvas and its workflow. The micro-DAG random sampler generates a kernel that contains two dynamic variables, \(x_{1}\) and \(x_{2}\). The solver by shape matching sets the value of \(x_{2}\) when merging the two branches into one. The solver by constraints assigns concrete values to the remaining \(x_{1}\) for each replacement target. The code generator implements the resultant kernels. Finally, the evaluator selects the best candidate according to accuracy and runtime measurements.
* What are the necessary fine-grained primitives KAS must incorporate to build high-quality kernels to allow for both rich expressibility and flexible construction?
* What sampling and search algorithms should KAS use to construct candidate kernels? How to balance the use of different primitives?
* How to effectively determine the legality of generated kernels with complex topologies, particularly when multiple branches interact and require matching dimension sizes?
* What interface and techniques should KAS use to satisfy various user-specified constraints, including FLOPs, parameter numbers, runtime, and accuracy?

## 4 Canvas Design Overview

As a concrete realization and an early milestone of KAS, we design _Canvas_ (CONVolution-like Architecture Search), an end-to-end, automated, and efficient framework. Figure 1 illustrates an overview of the system components in Canvas and their workflow.

**Main focus: convolutions.** Generally, KAS can be made to generate any type of kernels and integrate them into any NN backbone topology. In Canvas, we mainly focus on _Convolution_ Neural Networks (CNNs), which are the state-of-the-art solutions in many real-world application scenarios [19, 20, 21]. A convolution kernel takes a tensor of shape \([C_{\text{in}},H,W]\) as input, uses a set of \(K_{H}\times K_{W}\) filters to aggregate information from neighbor pixels on multiple channels, and produces a \([C_{\text{out}},H,W]\) output tensor. With Canvas, our goal is to generate new kernels with the same input and output shapes but with entirely different computational behaviors that improve performance and/or accuracy. Then we could replace standard convolutions with the new kernels in the same backbone NN topology. For simplicity, Canvas only searches for _a single kernel template_, which takes an input tensor of \([C,H,W]\) and produces an output tensor of the same shape \([C,H,W]\). For a general convolution of \([C_{\text{in}},H,W]\Rightarrow[C_{\text{out}},H,W]\), we observe that usually one of \(C_{\text{in}}\) and \(C_{\text{out}}\) is a multiple of the other, so it can be composed using the kernel template as shown in Figure 2. This allows Canvas to focus on optimizing a single kernel template shaped of \([C,H,W]\Rightarrow[C,H,W]\), amortizing the expensive search cost.

**Interface and functionality.** With a simple Python interface canvas.sample(nn, budget), users specify a backbone nn, and designates Canvas to sample a new kernel under the system budget. The user can specify budget using a variety of constraints and optimization goals, which we put into two categories. The first category includes constraints that can be _analytically calculated_, e.g., numbers of FLOPs and model parameters. The other category covers the constraints and goals that require _experimental measurements_, e.g., latency and accuracy.

**Workflow.** Following Figure 1, we briefly introduce the end-to-end workflow of Canvas. Canvas composes a library of various _fine-grained primitives_ as the building blocks (Section 5) and uses a _micro-DAG random sampler_ to build candidate kernel implementations. Starting from the input tensor, it extends the current micro-DAG by randomly sampling from the primitive library (Section 6.1). The sampler can also grow the micro-DAG into multiple branches. Finally, it merges the branches back because of the hard shape constraint of the single output tensor \([C,H,W]\)1.

Footnote 1: The kernel in Figure 1 is unfinished, a complete kernel after sampling should have exactly one output tensor shaped \([C,H,W]\).

Figure 2: A single kernel template of \([C,H,W]\Rightarrow[C,H,W]\) is applied to general convolutions with different \(C_{\text{in}}\) and \(C_{\text{out}}\) values.
However, some primitives (e.g., fully connected) may introduce intermediate tensors with arbitrary shapes. We use _dynamic variables_ (denoted as \(x_{i}\)) to represent such free dimensions and use a _solver by shape matching_ to coordinate the free variables in different branches so that they can match (Section 6.2). There could still be some dynamic variables left undetermined after the kernel structure is finalized. We use a _solver by constraints_ (Section 6.3) to solve their values according to the analytical constraints, e.g., numbers of FLOPs and parameters.

After all its dynamic variables are set, we apply each kernel candidate to the backbone NN. The code generator generates optimized code, and the evaluator uses a distributed platform to experimentally measure the rest constraints and goals.

## 5 Fine-Grained Primitives

Canvas uses a set of fine-grained primitives as the edges of the micro-DAG. It is critical to designate the appropriate granularity for these primitives. However, neither the techniques from the current system nor machine learning research satisfies this demand. The instruction and loop levels in tensor compilers are overly elaborative and would make the design space of constructing a kernel from scratch too large to be tackled; the existing NAS methods only work in a coarse-grained manner and offer limited flexibility to fine-tune performance and accuracy.

Instead, we observe that most of the neural operators, especially those applied on multi-dimensional tensors and aggregating neighbor information, could be decomposed into _data rearrangements_ and _actual arithmetic computations_. For example, a standard convolution first _unfolds_ the input \(I\) of shape \([C,H,W]\) using a receptive view \([K_{H},K_{W}]\), and produces a tensor \(U\) of shape \([C,K_{H},K_{W},H,W]\). This step does not actually copy neighbor pixels but rearranges data through shallow indexing: \(U(c,kh,kw,h,w)=I(c,h+kh,w+kw)\) (lowercase variables represent iterators while uppercase ones represent constants). Then, the actual computation is done by multiplying tensor \(U\) with a weight tensor to obtain the result. This decoupling has been there since convolutions appear, known as im2col [22]. It reflects the semantic understanding gap between system programmers and machine learning researchers. Similar reasoning can also be found in many other operators, especially those designed for lightweight computations: group convolution uses an rearrangement like \(U(g,c,kh,kw,h,w)=I(g\times\text{GROUP\_SIZE}+c,h+kh,w+kw)\); shift convolution applies an offset on a spatial dimension \(U(c,h,w)=I(c,h+1,w)\).

Following the above idea of decomposition, we conclude that the granularity of Canvas needs to follow this perspective of _rearrangement and computation decoupling_, which is more efficient than compiler primitives and more flexible than NAS building blocks. Moreover, to support complex topologies in a micro-DAG, primitives are needed to blend (i.e., merge) multiple branches. Consequently, we design our fine-grained primitive library in Canvas, which could be categorized into three classes summarized in Table 1.

**Rearrangement primitives.** The primitives in this class generalize the first type of operations in the above example. These primitives enable flexible data rearrangement across different channels and spatial dimensions in the tensor. For example, along a channel dimension, we could _group_ the data into \(G\) separate groups to apply subsequent intra-group transformations. With the \([H,W]\) spatial pixels, we could _shift_ the pixels to manipulate neighbor information. Finally, the _unfold_ primitive extracts spatial neighborhood information into the channel space.

**Arithmetic primitives.** This primitive class includes the arithmetic operators commonly used in NNs, which change the numerical value of a tensor. The most common one is _fully-connected_ (FC). It remaps all the channel dimensions into a new dimension with an arbitrary size, denoted by a dynamic variable \(x\) as the number of output channels. In our design, FC is the only primitive that contains learned parameters, a.k.a. weights. It is an essential primitive for NN functionality, but it also incurs higher cost than others, as well as the need to handle dynamic variables. Besides, we

\begin{table}
\begin{tabular}{c c l} \hline \hline
**Class** & **Primitive** & **Description and Shape Changes** \\ \hline \multirow{4}{*}{Rearrangement} & Group & Group a channel dim \(X\) by a factor \(G\) or make each individual channel as a group: \\  & \([\cdots,X,\cdots]\Rightarrow[\cdots,G,\frac{\nabla}{G},\cdots]\) or \([\cdots,X,1,\cdots]\) \\  & Shift by 1 pixel at a spatial dim: \([\cdots,X,\cdots]\Rightarrow[\cdots,X_{+1},\cdots]\) \\  & Unfold & Unfold \(K\) neighbors of spatial dim \(X\) to a channel dim: \\  & \([\cdots,X,\cdots]\Rightarrow[\cdots,K_{X},\cdots,X,\cdots]\) \\ \hline \multirow{4}{*}{Arithmetic} & Fully-connected & Remap values at all channels to a new dim \(x\): \([\cdots_{\text{`channel}},\cdots]\Rightarrow[x,\cdots]\) \\  & Element-wise & ReLU, abs, \(\sin,\exp\), etc.: \([\cdots]\Rightarrow[\cdots]\) \\  & Folding & Average/max pooling at any dim \(X\): \([\cdots,X,\cdots]\Rightarrow[\cdots,\cdots]\) \\  & Softmax & Softmax at any continuous dims: \([\cdots,\cdots]\Rightarrow[\cdots,\cdots],\cdots]\) \\ \hline Blending & Broadcast & Broadcasting add/sub/mul/min/max from LHS to RHS: \([\cdots]_{\text{LBS}}\), \([\cdots]_{\text{RIS}}\Rightarrow[\cdots]_{\text{RIS}}\) \\ \hline \hline \end{tabular}
\end{table}
Table 1: Three classes of fine-grained primitives used in Canvas.
have _element-wise/activation_ functions (ReLU, abs, etc.), _folding_ (average pooling at a certain dimension), and _softmax_. All of them are simple and cheap operators but could be helpful to introduce non-linearity and other properties to the data.

**Blending primitives.** To eventually produce a single output tensor, the kernel micro-DAG must merge the multiple branches which may grow during the random sampling process (Section 6.1). Having such a capability allows us to support advanced complex connections, such as residual blocks (broadcasting addition) [23]. To blend two tensors into one, we introduce the _broadcast_ primitive. It takes two tensors \(\mathrm{LHS}\) and \(\mathrm{RHS}\) as inputs and produces an output tensor with the same shape as \(\mathrm{RHS}\). To do so, we denote the two input shapes in the form of \([\cdots\) common prefix \(\cdots\) LHS, \(\cdots\) common suffix] and \([\cdots\) common prefix \(\cdots\) RHS, \(\cdots\) common suffix]. The data on the dimensions \([\cdots\) LHS\(]\) are broadcast to \([\cdots\) RHS\(]\), i.e., replicated multiple times and applied to \(\mathrm{RHS}\) through a binary operation like addition, subtraction, or multiplication. This requires the total size of \([\cdots\) LHS\(]\) dimensions must be a factor of that \([\cdots\) RHS\(]\). For example, broadcasting \([G,\frac{x_{1}}{G},H,W]\) to \([G,\frac{C}{G},K_{H},H,W]\) expects that \(\frac{x_{1}}{G}\) is a factor of \(\frac{C}{G}\times K_{H}\). Such dimension matching introduces a new challenge about dynamic variable substitution, which we resolve in Section 6.2.

**Expressibility of our primitive library.** The fine-grained primitive library is sufficiently expressive to explore a large design space of kernel construction, including complex manual designs by previous works. Take Involution [24] for a detailed illustration, which is embedded in Figure 1. The central part is a broadcast multiplication between two tensors \([G,K,K,H,W]\) and \([G,C/G,K,K,H,W]\). We can first generate them from the input tensor using group and unfold primitives, temporally as \([G,x_{2}/G,H,W]\) and \([G,C/G,K,K,H,W]\). Then we try to blend them with broadcasting and substitute \(x_{2}=GKK\). In the end, we still have a free variable \(x_{1}\), which can be easily scaled to realize different FLOPs and model sizes (Section 6.3). Note that this is just one specific sample in the large design space. In our experiments, we indeed observe that almost all manual designs appear during the search or in the final results, among other previously unexplored constructions.

## 6 Kernel Generation

In Canvas, the micro-DAG random sampler stochastically and iteratively generates a large number of candidate kernels by sampling from the primitive library. Section 6.1 describes the sampling algorithm and our pruning techniques. A key challenge is to assign values to dynamic variables to ensure legality. We first propose a variable solver in Section 6.2 to address the problem in the sampling process. Finally, Section 6.3 resolves any remaining variables after primitive sampling according to the analytical constraints.

### Sampling Algorithm

Given the high flexibility of constructing complex micro-DAGs from the rich set of primitives, Canvas uses random sampling. Canvas builds the micro-DAG from one node with the shape of input tensor: \([C,H,W]\). We iteratively grow it to \(N\) nodes, where \(N\) is a hyperparameter. In the step \(t\), we have \(n_{t}=|V_{t}|\) nodes in \(g_{t}\). We calculate all possible single-input primitives \(\{p_{t}^{i}\}\) for each node \(v_{t}^{i}\) and blending primitives \(\{p_{t}^{i,j}\}\) for each pair of nodes \((v_{t}^{i},v_{t}^{j})\). Then one primitive \(e_{t}\) is selected from \(\tilde{E}_{t}=\{\{p_{t}^{1}\},\{p_{t}^{2}\},...,\{p_{t}^{n_{t}}\},\{p_{t}^{1,2 }\},\{p_{t}^{1,3}\},...,\{p_{t}^{n_{t}-1,n_{t}}\}\}\). Then \(E_{t+1}=\{E_{t},e_{t}\}\). After deciding the \(e_{t}\), we add to \(g_{t}\) the new node derived from input node(s) of \(e_{t}\) and get \(g_{t+1}\).

**Sampling probability adjustment.** A key innovation in the random sampler is the need to carefully adjust the sampling probability of each primitive. There are two reasons. First, notice that the number of choices from \(\{p_{t}^{i}\}\) and \(\{p_{t}^{i,j}\}\) are drastically different, i.e., \(O(n)\) vs. \(O(n^{2})\). Uniformly sampling from \(\tilde{E}_{t}\) would result in a large bias towards the blending primitives. We hence re-scale the probability of each primitive so that the sampling is uniform w.r.t. each primitive type, regardless of \(n_{t}\).

**Topology heuristics.** Moreover, micro-DAG is constrained by certain topology properties. We must ensure that \(n_{T}=N\) for the final step \(T\), and \(n_{T}=n_{T-1}+1\). Therefore, we need to heuristically restrict the number of leaf nodes in \(g_{t}\), which we term as \(W(g_{t})\). During construction, we examine the number of remaining primitives \(N-n_{t}\) to see whether we are allowed to further extend more branches or must start to merge. For example, if \(W(g_{t})=3\) and \(N-n_{t}=2\), we must combine two tensors. We control such behaviors by modifying the sampling probability of primitives, e.g., by setting all probabilities to 0 except for blending primitives.

**Pruning techniques.** Random sampling is an expensive process. We apply several pruning heuristics to improve its efficiency. We use an approximate graph isomorphism hash function similar to [25] and deduplicate generated kernels. Besides, we eliminate obviously sub-optimal constructions with redundant or illegal components, such as consecutive ReLUs and subtracting two equal tensors. With such pruning, Canvas is able to sample a legal kernel candidate in the huge search space within a few milliseconds.
### Dynamic Variable Solver by Shape Matching

During the sampling process mentioned above, the FC primitives in our candidate micro-DAG produce free dynamic variables. These dynamic variables further enlarge the search space and provide more flexibility to tune the numbers of FLOPs and parameters in our kernel for performance-accuracy tradeoffs. Recall that an FC primitive uses weights to remap \([\cdots`_{\text{channel}},\cdots`_{\text{spatial}}]\) into \([x,\cdots`_{\text{spatial}}]\), where \(x\) indicates that the output channel dimension can have any size. Other primitives typically have deterministic dimensions without introducing variables.

The concrete values of all dynamic variables will be eventually assigned according to the constraints such as FLOPs and model sizes (Section 6.3). However, not all variables can be independently set in the micro-DAG. In particular, the blending primitive that combines two tensors requires matched dimension sizes of the two inputs. For example, when a tensor \([x_{1},H,W]\) is broadcast to another tensor \([C,K_{H},H,W]\), \(x_{1}\) must be a factor of \(CK_{H}\). By default, the group number \(G\) is a factor of \(C\). So \(x_{1}\) can only take a value from the set \(\{C,K_{H},G,\frac{C}{G},CK_{H},GK_{H},\frac{C}{G}\times K_{H}\}\), which is an additional constraint that must be satisfied.

To handle such constraints among dynamic variables in a general way, we first prove a simple theorem.

**Theorem 1**: _For any tensor constructed in Canvas where all its dimensions are in the form of \(D=\frac{\text{numerator}}{\text{denominator}}\) (e.g. \(D=\frac{C}{G}\) or \(D=CK_{H}\)), there is_

* _no dynamic variable in any spatial dimension (i.e.,_ \([C,H,x_{0}]\) _does not exist);_
* _no dynamic variable in the denominator of a channel dimension (i.e.,_ \(\frac{C}{x_{0}}\) _does not exist);_
* _at most one dynamic variable in the numerator of a channel dimension (i.e.,_ \(\frac{x_{0}x_{1}}{K_{H}}\) _does not exist);_
* _at most one dynamic variable across all dimensions (i.e.,_ \([x_{0},x_{1},H,W]\) _does not exist)._

**Proof sketch.** We prove this by induction. For the input tensor shaped \([C,H,W]\), the theorem naturally holds. For all primitive types except FC, the shape transformation neither introduces new dynamic variables nor moves an existing dynamic variable to a denominator. For an FC primitive, all channel dimensions are remapped to a new dimension with a single dynamic variable \(x\). With the fact that no primitives introduce dynamic variables into spatial dimensions, the theorem holds. \(\square\)

Theorem 1 simplifies the design to substitute dynamic variables for broadcast primitives in Canvas. For two tensors' shape denoted as \([\cdots`_{\text{common prefix}},\cdots`_{\text{LHS}},\cdots`_{\text{common suffix}}]\) and \([\cdots`_{\text{common prefix}},\cdots`_{\text{RHS}},\cdots`_{\text{common suffix}}]\), we first detect and strip the common prefix and suffix and focus on the unmatched parts \(\{\cdots`_{\text{LHS}}\}\) and \(\{\cdots`_{\text{RHS}}\}\). We calculate their total sizes as \(\#\{\cdots`_{\text{LHS}}\}=\frac{\Pi_{\text{numerator}}_{\text{LHS},,,,}}{\Pi _{\text{d}},\text{denominator}_{\text{LHS},,,}}\), and similarly for \(\#\{\cdots`_{\text{RHS}}\}\). Theorem 1 says that only one dynamic variable could exist in the numerator of each, which we use \(k_{\{\text{LHS},\text{RHS}\}}\in\{0,1\}\) to indicate. So if we take the ratio \(M\) between the two sizes, we have:

\[M=\frac{\#\{\cdots`_{\text{RHS}}\}}{\#\{\cdots`_{\text{LHS}}\}}=\frac{(x_{ \text{RHS}})^{k_{\text{RHS}}}R_{\text{RHS}}}{(x_{\text{LHS}})^{k_{\text{LHS}} }R_{\text{LHS}}}\]

where \(R_{\text{LHS}}\) and \(R_{\text{RHS}}\) are fully simplified as remaining factors.

To ensure legality in broadcast, \(M\) must be an integer, which determines the possible values for dynamic variables \(x_{\text{LHS}}\) and \(x_{\text{RHS}}\) (if existing). This mainly constrains \(x_{\text{RHS}}\) in the denominator, which should be a factor of the numerator. Naturally, the valid substitutions of \(x_{\text{LHS}}\) are the set of all factors of \((x_{\text{RHS}})^{k_{\text{RHS}}}R_{\text{RHS}}\). As an example, assume two tensors \([x_{1},K_{H},H,W]\) and \([G,\frac{x_{2}}{G},K_{H},K_{W},H,W]\). The common prefix is empty, and the common suffix is \(\{H,W\}\), which are stripped. The substitutions of \(x_{1}\) could be all the factors of \(x_{2}K_{W}\), i.e., \(\{1,x_{2},K_{W},x_{2}K_{W}\}\).

Once we have the valid substitution set from the dynamic variable solver, the random sampler will randomly select one value and propagate to the whole micro-DAG. For example, assume we sample \(x_{1}=x_{2}K_{W}\), then the shape of \(\text{LHS}\) becomes \([x_{2}K_{W},K_{H},H,W]\).

### Dynamic Variable Solver by Analytical Constraints

After some of the dynamic variables are solved in the generation process, the remaining variables should still be carefully considered and assigned according to all _analytical constraints_, e.g., FLOPs and parameter sizes.

Generally speaking, the generated kernel template needs to substitute multiple standard convolutions in an NN. Each individual convolution has a specific assignment of \(C\), \(K_{H}\), \(K_{W}\), \(H\), \(W\), \(G\), as well as the dynamic variables \(x\). For these remaining dynamic variables, we denote them as \(x_{i,j}\), i.e., the \(j\)-th variable in the \(i\)-th convolution target. The constraint solver derives all values of \(x_{i,j}\) using a heuristic algorithm to maximally utilize the available budget of the constraints that can be analytically modeled, e.g., FLOPs and parameter sizes.
Before dealing with \(x_{i,j}\), we first specially handle the group number \(G\). We observe that most of the modern NN designs that adopt group convolutions [26, 27] usually apply the same number of groups in almost all their layers. Therefore we enforce a global value \(G\) for all the group primitives across _all_ targets in the NN. \(G\) must be a common factor of the original channel numbers \(C_{i}\) of these replaced convolutions, i.e., \(G\) is a factor of \(\gcd(C_{i})\). For example, with two targets of \(C_{1}=32\) and \(C_{2}=48\), \(G\) should be sampled from a set of \(\{2,4,8,16\}\). It simplifies our dynamic variable solver by excluding \(G\) from free variables.

Now, all remaining \(x_{i,j}\) variables were generated by FC primitives as the output channel dimensions. They directly contribute to the FLOPs, the number of parameters, and model accuracy. Our heuristic algorithm sets their values in two steps. First, as each \(x_{i,j}\) denotes a channel dimension, it should roughly match the channel number of the input/output tensor at the target. The solver thus derives the base (i.e., minimum) value of each \(x_{i,j}\) that satisfies structural legality and is proportional to the input channel number \(C_{i}\). Second, more channels (thus higher FLOPs and more parameters) usually help improve model accuracy. So the solver tries to fully utilize the allowed constraint budget by using the maximum value for each \(x_{i,j}\), which is a multiple of the above base \(x_{i,j}\).

Specifically, we should first satisfy the legality of individual dimension sizes and broadcast primitives, similar to Section 6.2. Recall from Theorem 1 that any \(x_{i,j}\) only appears in numerators, i.e., the dimension size is in the form of \(\frac{p\cdot x_{i,j}}{q}\). Each variable may appear in more than one primitive in each kernel; so for each \(x_{i,j}\), there may exist multiple pairs of \((p,q)\) (after fully reduced, \(\gcd(p,q)=1\)). To ensure integer dimension sizes, we must have:

\[x_{i,j}=k_{i,j}\times\mathrm{lcm}(q_{1},q_{2},\cdots)\stackrel{{ \mathrm{def}}}{{=}}k_{i,j}\times\mathrm{lcm}_{i,j},\quad k_{i,j}\in \mathbb{Z}^{+}\]

where \(\mathrm{lcm}_{i,j}\) is the least common multiple of all _qs_.

To make each \(x_{i,j}\) proportional to the corresponding \(C_{i}\), without loss of generality, we assume \(C_{1}=\min_{i}(C_{i})\). We require approximately that:

\[\frac{x_{i,j}}{x_{1,j}}=\frac{k_{i,j}\times\mathrm{lcm}_{i,j}}{k_{1,j}\times \mathrm{lcm}_{1,j}}\approx\frac{C_{i}}{C_{1}}\]

By setting \(k_{1,j}=1\), we obtain a series of the base \(x_{i,j}\) values that satisfy legality and heuristically retain channel scaling throughout the network:

\[k_{i,j}=\frac{C_{i}\times\mathrm{lcm}_{1,j}}{C_{1}\mathrm{lcm}_{i,j}}\approx \lceil\frac{C_{i}\times\mathrm{lcm}_{1,j}}{C_{1}\mathrm{lcm}_{i,j}}\rceil,\:x_ {i,j}=k_{i,j}\times\mathrm{lcm}_{i,j}\]

In the second step, we fully utilize the budget of each analytical constraint. Assume a constraint \(\text{Cstr}(\text{net}(\{x_{i,j}\}))\leq\text{budget}\), where Cstr could be FLOPs, parameter sizes, or other constraint functions. If even the previously solved base \(x_{i,j}\) values violate the constraint, we discard this kernel and sample the next. Otherwise, we try to increase these variables according to their utilization sensitivities. Specifically, we calculate each \(\Delta_{i,j}=\text{Cstr}(\text{net}(\cdots,2x_{i,j},\cdots))-\text{Cstr}(\text{ net}(\cdots,x_{i,j},\cdots))\), and double the \(x_{i,j}\) by the ascending order of \(\Delta_{i,j}\) at each iteration, until we cannot further increase any \(x_{i,j}\) without exceeding the budget.

Figure 3 illustrates an example, where the broadcast primitive between \([GK_{H},H,W]\) and \([x_{1},H,W]\) requires \(x_{1}\) must be a multiple of \(GK_{H}\). Applying it to the two layers gives \(\mathrm{lcm}_{1,1}=GK_{1,H}=12\) and \(\mathrm{lcm}_{i,1}=GK_{i,H}=20\). Scaling by \(C\), we have \(x_{1,1}=12\) and \(x_{i,1}=\lceil\frac{C_{i}\mathrm{lcm}_{1,1}}{C_{1}\mathrm{lcm}_{i,1}}\rceil x _{1,1}=60\). Finally, to fully utilize the budget, we double the values two times and get \(x_{1,1}=48\) and \(x_{i,1}=240\).

## 7 Kernel Evaluation

After substituting all variables, we now have a concrete kernel instance for each replacement target. Canvas next generates code implementation and measures the runtime and accuracy on real hardware platforms.

**Code generation and runtime evaluation.** Canvas does code generation for PyTorch and TVM separately. It translates the kernels to nn.Module classes in PyTorch and uses them to build the entire model for training. We also translate kernels into TVM Tensor Expression language [11] and use TVM Ansor [7] for performance-oriented machine code generation and tuning. The code generation also includes several optimizations passes, e.g., adding normalization for numeric stability and other common compiler optimizations.

**Model accuracy evaluation.** Fully training a typical NN usually takes hours to days, depending on the model size. Existing NAS techniques reduce such overheads by using proxy datasets [15], fewer epochs [28, 15], zero-cost estimation [29, 30], or other early-pruning techniques. All these solutions could be directly incorporated in Canvas. We also developed a new pruning strategy that we empirically find very effective. We record the accuracy curve (accuracy vs. epochs) of the best accuracy result achieved so far. When training a new candidate, we require the
accuracy at each epoch to be at least a given fraction of the accuracy of the recorded best result at the same epoch, i.e., \(\text{accuracy}_{\text{ker}}(\text{epoch})\geq\lambda\cdot\text{accuracy}_{\max}( \text{epoch})\), where \(\lambda=f(\text{epoch})\) and \(f(x)=\theta+(1-\theta)x\). Basically, \(\lambda\) is small at early epochs and gets larger later, so we allow a kernel to perform less effectively at an early stage but eventually should approach the best result. \(\theta\) adjusts the pruning strictness and is typically set to 0.5.

**Implementation: distributed evaluation infrastructure.** We develop a platform to automatically dispatch runtime/accuracy evaluation tasks to a distributed pool of workers, e.g., GPUs for accuracy tasks and CPU cores for runtime tasks. Due to the high parallelism in our random sampling algorithm and the complete independence of all tasks, this infrastructure has superior scalability. This is desired as it offers a nice benefit vs. cost tradeoff: the more computing resources you use, the higher rewards in terms of better kernel implementations you may get. In contrast, more advanced algorithms such as evolutionary search [31] may suffer from the inefficiency caused by heavy task dependency and cannot scale well. We implemented all the procedures as a distributed and end-to-end framework with 8,000 lines of C++ and 6,000 lines of Python.

## 8 Results

### Experimental Setups

**Hardware configurations.** We use a cluster of four nodes, each with two sockets of 20-core Intel(r) Xeon(r) Gold 5218R processors, 256 GB of DRAM, and four RTX(tm) 3090 GPUs.

**Workloads.** We choose 8 commonly used NNs: ResNet-18 [23], ResNet-29 [23], VGG-16 [32], DenseNet-161 [33], MobileNet-V2 [34], ResNeXt-29-2x64D [26], RegNet-X-800MF [27], and MNASNet-1-0 [4]. We set the replacement targets to be all standard convolutions in these NNs.

**Baselines.** We use two baselines for comparison. TVM Ansor [7] is a state-of-the-art tensor compiler that preserves mathematical equivalence during optimizations and provides performance with the original models. Turner et al. [2] (labeled as NAS-PTE, as mentioned in Section 2) is the first work that introduced NAS-style transformations into tensor program optimizations, but at a preliminary stage which only involves simple loop range number changing and is still in the traditional scope of convolution semantics.

**Datasets and training configurations.** ImageNet [35] has been the standard benchmark for CNNs, but it is not suitable for directly searching because of the large size. We use the smaller but still relatively challenging CIFAR-100 [36] as the proxy dataset. Specifically, NN models are fully trained for 300 epochs on CIFAR-100 (may early stop due to the pruning in Section 7) using stochastic gradient descent (SGD) [37]. The selected best kernels under CIFAR-100 are then fully trained on the ImageNet dataset for 90 epochs, also using SGD, for accuracy and performance evaluation. We scale the CIFAR-100 images to the same size as ImageNet to ensure the same inference performance.

Figure 3: An example of solving dynamic variables for different convolution targets by the constraint solver.
### End-to-End Performance

We first compare the end-to-end performance between Canvas and the two baselines. Figure 4 shows the performance results among all the workloads. In Canvas, we keep reducing the specified FLOPs budget and see how far we can go in terms of actual runtime performance with no more than 1% loss in CIFAR-100 accuracy. NAS-PTE only searched for network-independent efficient kernel designs and later applied manual layer-wise optimizations to put them into an NN. Due to the manual optimizations and code unavailability of NAS-PTE, we only report the results which can be derived from their published search results; the other NNs with missing numbers in Figure 4 are not evaluated.

We observe that Canvas achieves up to \(4.6\times\) of speedup and obtain an average (geomean) speedup of \(1.5\times\) across all workloads compared to the Ansor-compiled baselines. For early NNs like ResNet-18, ResNet-34, and VGG-16, Canvas performs \(3\times\) better due to the discovered novel kernels. Even for relatively new and highly optimized NNs, Canvas is still able to achieve \(1.05\sim 2\times\) gains. Compared to NAS-PTE, we also achieve \(1.4\times\) and \(1.6\times\) speedups on ResNet-34 and ResNeXt-29, even considering that NAS-PTE incorporated manual analysis and tuning and Canvas is fully automated. DenseNet-161 uses a large number of convolutions with the irregular matching of input and output channel numbers, which does not satisfy Canvas's assumption that one is a multiple of the other. So we can only replace \(60\%\) of the FLOPs that bounds the ideal speedup at \(2.5\times\), while we achieve \(1.56\times\).

All Canvas-discovered NNs have less than 1% accuracy loss on CIFAR-100. When retrained on ImageNet, they exhibit approximately 4% accuracy loss, which is acceptable and comparable to state-of-the-art numeric pruning techniques summarized in [38] (reducing \(\geq 50\%\) FLOPs or parameters) from the machine learning community.

**Search efficiency.** With the efficient sampler, solver, and pruning designs, Canvas, as a KAS implementation, has reasonable search speedup. During two weeks of experiments on our cluster of 16 GPUs, over 300,000 kernels were evaluated, translating to 0.01 GPU hours per kernel.

### Model Size Reduction

We also present the model size comparison in terms of parameter numbers in Figure 5. Almost all models benefit from the Canvas design, with the new model being only \(0.1\times\) to \(0.6\times\) of the original size. VGG-16 contains a significant amount (\(89\%\)) of model parameters in its final classifier layer. As Canvas only focuses on convolution replacements, we are not able to reduce the final classifier layer. Excluding the classifier brings the model size ratio with the replaced kernel to \(0.13\times\). For classical NN designs like ResNet-18, ResNet-34, or VGG-16, we are able to compress the model size to \(\sim 0.1\times\). Even for the relatively new models, which are specifically targeted for small model sizes _by design_, Canvas can further reduce the sizes into at least \(0.5\times\).

### Kernel-Level Analysis of ResNet-34

Figure 6 shows the best result of our search on ResNet-34. Instead of collecting information from all neighbors by unfolding, this kernel uses a combination of shift and addition to extract features from only one adjacent pixel in order to significantly reduce FLOPs and parameters. There is also another branch that uses a lightweight depth-wise convolution (FC within each channel separately, i.e., grouping and FC) to maintain expressive power and generalization.

Figure 4: End-to-end performance comparison between Canvas and the baselines.
Figure 7 summarizes all individual layer performance on ResNet-34, compared to TVM Ansor and all the three kernel structures discovered by NAS-PTE. Our kernel outperforms the traditional convolution by up to \(9.45\times\). Compared to the optimized kernels from NAS-PTE, Canvas is on average \(2.2\times\), \(1.7\times\), and \(1.2\times\) faster, respectively. These improvements are achieved without any layer-wise tuning by a fully automated workflow in Canvas.

### Case Study: Machine Learning Kernels

To understand what kernels Canvas can find, we study its discoveries from both historical and future views.

**Rediscovering designs in the past.** Interestingly, Canvas can rediscover several convolution variants that researchers proposed previously. For example, on VGG [32], a very early linear network, the top kernels discovered by Canvas resemble the residual connections [23], using Canvas's broadcast primitives. On ResNet itself, Canvas finds depth-wise separable [39], and spatial separable [40] convolutions. Finally, for MobileNet [39], the resultant kernels include optimizations of pooling and folding, very similar to Squeeze-and-Excitation convolutions [41] and Involution [24].

Canvas not only finds these designs but also cleverly combines them to best exploit their properties. For example, Canvas expresses the aggregation of neighborhood information in one dimension and combines it with a shift primitive in another dimension to achieve lightweight but comprehensive feature extraction. In Figure 8, each unfold primitive can extract the information of 3 surrounding pixels. Applying unfold on both dimensions (bottom left) covers all 9

Figure 5: Model size comparison between the original size and that discovered by Canvas, for both the entire network and the feature extraction front-end excluding the final classifiers. Each number indicates the ratio of the new model size compared to the original size.

Figure 6: Best kernel found for ResNet-34.

Figure 7: ResNet-34 layer-wise performance comparison between TVM Ansor, NAS-PTE, and Canvas.
neighboring pixels, with 9 parameters and 9 FLOPs. Instead, if we use an unfold and a shifted residual connection on the two dimensions, respectively (bottom right), we can use information from 6 neighboring pixels but reduce it to only 3 parameters and 4 FLOPs.

**Motivating the future.** Canvas finds many interesting and previously unexplored kernel designs with high accuracy and performance. On ResNet, Canvas finds a design with spatial aggregation and kernel spanning, as kernel A in Figure 9. Traditional convolutions only operate on neighbor pixels. Kernel A first aggregates \([C,H,W]\) into an overall spatial vector \([C]\) by pooling and then generates an FC primitive with shape \([H\times W]\). It finally multiplies this tensor with the input to get the output, which is unexpectedly similar to the popular attention mechanism [42]. With Canvas's variable system and shape-matching rules, such irregularities are extremely abundant in generated kernels.

A surprising finding is that, although we search for individual kernels, we end up with some primitives that do not materially affect the current kernel but are an integral part of the overall design. For example, in kernel B in Figure 9, all primitives inside the kernel only operate on channel dimensions; any spatial shift does not change the numerical results but only rearranges the pixel positions. However, when this kernel is placed in a residual connection, the shift primitive contributes to the output of the whole residual connection. This is a good demonstration of Canvas's ability to search for customized kernels in an end-to-end manner.

## 9 Conclusions

We make a case for a new paradigm of Kernel Architecture Search, which stochastically explores new kernel constructions. To demonstrate such potential, we further build an end-to-end system, Canvas. Canvas has a random sampler to construct kernel structures from a library of fine-grained primitives, two solvers to address tensor dimension flexibility, and an evaluation system to handle analytical and experimental constraints. Our results show Canvas achieves on average \(1.5\times\) and up to \(4.6\times\) performance improvements.

Figure 8: Fine-grained combination of unfold and shift.

Figure 9: Two new kernel patterns discovered by Canvas. The first shows the dynamic variable system enables irregular designs; the second shows an out-of-kernel opportunity.