Published as a conference paper at ICLR 2021 GRAPH CODE BERT: P RE-TRAINING CODE REPRESEN - TATIONS WITH DATA FLOW Daya Guo1∗, Shuo Ren2∗, Shuai Lu3∗, Zhangyin Feng4∗, Duyu Tang5, Shujie Liu5, Long Zhou5, Nan Duan5, Alexey Svyatkovskiy6, Shengyu Fu6, Michele Tufano6, Shao Kun Deng6, Colin Clement6, Dawn Drain6, Neel Sundaresan6, Jian Yin1, Daxin Jiang7, and Ming Zhou5 1School of Computer Science and Engineering, Sun Yat-sen University. 2Beihang University, 3Peking University, 4Harbin Institute of Technology, 5Microsoft Research Asia, 6Microsoft Devdiv, 7Microsoft STCA ABSTRACT Pre-trained models for programming language have achieved dramatic empirical improvements on a variety of code-related tasks such as code search, code comple- tion, code summarization, etc. However, existing pre-trained models regard a code snippet as a sequence of tokens, while ignoring the inherent structure of code, which provides crucial code semantics and would enhance the code understanding process. We present GraphCodeBERT, a pre-trained model for programming language that considers the inherent structure of code. Instead of taking syntactic-level structure of code like abstract syntax tree (AST), we use data flow in the pre-training stage, which is a semantic-level structure of code that encodes the relation of “where- the-value-comes-from” between variables. Such a semantic-level structure is less complex and does not bring an unnecessarily deep hierarchy of AST, the property of which makes the model more efficient. We develop GraphCodeBERT based on Transformer. In addition to using the task of masked language modeling, we introduce two structure-aware pre-training tasks. One is to predict code structure edges, and the other is to align representations between source code and code structure. We implement the model in an efficient way with a graph-guided masked attention function to incorporate the code structure. We evaluate our model on four tasks, including code search, clone detection, code translation, and code refine- ment. Results show that code structure and newly introduced pre-training tasks can improve GraphCodeBERT and achieves state-of-the-art performance on the four downstream tasks. We further show that the model prefers structure-level attentions over token-level attentions in the task of code search.1 1 I NTRODUCTION Pre-trained models such as ELMo (Peters et al., 2018), GPT (Radford et al., 2018) and BERT (Devlin et al., 2018) have led to strong improvement on numerous natural language processing (NLP) tasks. These pre-trained models are first pre-trained on a large unsupervised text corpus, and then fine-tuned on downstream tasks. The success of pre-trained models in NLP also promotes the development of pre-trained models for programming language. Existing works (Kanade et al., 2019; Karampatsis & Sutton, 2020; Feng et al., 2020; Svyatkovskiy et al., 2020; Buratti et al., 2020) regard a source code as a sequence of tokens and pre-train models on source code to support code-related tasks such as code search, code completion, code summarization, etc. However, previous works only utilize source code for pre-training, while ignoring the inherent structure of code. Such code structure provides useful semantic information of code, which would benefit the code understanding process. Taking the expression v= max value−min valueas an example, vis computed from max valueand min value. Programmers do not always follow the naming conventions so that it’s hard to understand the semantic of the variable vonly from its name. The semantic structure of code provides a way to understand the semantic of the variable vby leveraging dependency relation between variables. ∗Work done while this author was an intern at Microsoft Research Asia. Contact: Daya Guo (guody5@mail2.sysu.edu.cn) 1All the codes and data are available at https://github.com/microsoft/CodeBERT. 1 arXiv:2009.08366v4 [cs.SE] 13 Sep 2021 Published as a conference paper at ICLR 2021 In this work, we present GraphCodeBERT, a pre-trained model for programming language that considers the inherent structure of code. Instead of taking syntactic-level structure of code like abstract syntax tree (AST), we leverage semantic-level information of code, i.e. data flow, for pre- training. Data flow is a graph, in which nodes represent variables and edges represent the relation of “where-the-value-comes-from” between variables. Compared with AST, data flow is less complex and does not bring an unnecessarily deep hierarchy, the property of which makes the model more efficient. In order to learn code representation from source code and code structure, we introduce two new structure-aware pre-training tasks. One is data flow edges prediction for learning representation from code structure, and the other is variable-alignment across source code and data flow for aligning representation between source code and code structure. GraphCodeBERT is based on Transformer neural architecture (Vaswani et al., 2017) and we extend it by introducing a graph-guided masked attention function to incorporate the code structure. We pre-train GraphCodeBERT on the CodeSearchNet dataset (Husain et al., 2019), which includes 2.3M functions of six programming languages paired with natural language documents. We evaluate the model on four downstream tasks: natural language code search, clone detection, code translation, and code refinement. Experiments show that our model achieves state-of-the-art performance on the four tasks. Further analysis shows that code structure and newly introduced pre-training tasks can improve GraphCodeBERT and the model has consistent preference for attending data flow. In summary, the contributions of this paper are: (1) GraphCodeBERT is the first pre-trained model that leverages semantic structure of code to learn code representation. (2) We introduce two new structure-aware pre-training tasks for learning representation from source code and data flow. (3) GraphCodeBERT provides significant improvement on four downstream tasks, i.e. code search, clone detection, code translation, and code refinement. 2 R ELATED WORKS Pre-Trained Models for Programming LanguagesInspired by the big success of pre-training in NLP (Devlin et al., 2018; Yang et al., 2019; Liu et al., 2019; Raffel et al., 2019), pre-trained models for programming languages also promotes the development of code intelligence (Kanade et al., 2019; Feng et al., 2020; Karampatsis & Sutton, 2020; Svyatkovskiy et al., 2020; Buratti et al., 2020). Kanade et al. (2019) pre-train a BERT model on a massive corpus of Python source codes by masked language modeling and next sentence prediction objectives. Feng et al. (2020) propose CodeBERT, a bimodal pre-trained model for programming and natural languages by masked language modeling and replaced token detection to support text-code tasks such as code search. Karampatsis & Sutton (2020) pre-train contextual embeddings on a JavaScript corpus using the ELMo framework for program repair task. Svyatkovskiy et al. (2020) propose GPT-C, which is a variant of the GPT-2 trained from scratch on source code data to support generative tasks like code completion. Buratti et al. (2020) present C-BERT, a transformer-based language model pre-trained on a collection of repositories written in C language, and achieve high accuracy in the abstract syntax tree (AST) tagging task. Different with previous works, GraphCodeBERT is the first pre-trained model that leverages code structure to learn code representation to improve code understanding. We further introduce a graph- guided masked attention function to incorporate the code structure into Transformer and two new structure-aware pre-training tasks to learn representation from source code and code structure. Neural Networks with Code StructureIn recent years, some neural networks leveraging code structure such as AST have been proposed and achieved strong performance in code-related tasks like code completion (Li et al., 2017; Alon et al., 2019; Kim et al., 2020), code generation (Rabinovich et al., 2017; Yin & Neubig, 2017; Brockschmidt et al., 2018), code clone detection (Wei & Li, 2017; Zhang et al., 2019; Wang et al., 2020), code summarization (Alon et al., 2018; Hu et al., 2018) and so on (Nguyen & Nguyen, 2015; Allamanis et al., 2018; Hellendoorn et al., 2019). Nguyen & Nguyen (2015) propose an AST-based language model to support the detection and suggestion of a syntactic template at the current editing location. Allamanis et al. (2018) use graphs to represent programs and graph neural network to reason over program structures. Hellendoorn et al. (2019) propose two different architectures using a gated graph neural network and Transformers for combining local and global information to leverage richly structured representations of source code. However, these 2 Published as a conference paper at ICLR 2021 works leverage code structure to learn models on specific tasks from scratch without using pre-trained models. In this work, we study how to leverage code structure for pre-training code representation. 3 D ATA FLOW In this section, we describe the basic concept and extraction of data flow. In next section, we will describe how to use data flow for pre-training. Data flow is a graph that represents dependency relation between variables, in which nodes represent variables and edges represent where the value of each variable comes from. Unlike AST, data flow is same under different abstract grammars for the same source code. Such code structure provides crucial code semantic information for code understanding. Taking v= max value−min valueas an example, programmers do not always follow the naming conventions so that it is hard to understand the semantic of the variable. Data flow provides a way to understand the semantic of the variable vto some extent, i.e. the value of vcomes from max valueand min valuein data flow. Besides, data flow supports the model to consider long-range dependencies induced by using the same variable or function in distant locations. Taking Figure 1 as an example, there are four variables with same name (i.e. x3, x7, x9 and x11) but with different semantic. The graph in the figure shows dependency relation between these variables and supports x11 to pay more attention to x7 and x9 instead of x3. Next, we describe how to extract data flow from a source code. defmax(a,b):x=0ifb>a:x=belse:x=areturnx SourcecodeParseintoAST CompilerTool Identifyvariable sequence5 13 67 8 910 4 2 11 defmax(a,b):x=0ifb>a:x=belse:x=areturnx Identify variable sequence in AST Variable relation ab x0babxaxx 1 2 3 4 6 5 1089 7 11 Extract variable relation from AST Valuecomesfrom… function definition nameparameters maxa b body expressionstatement assignment leftright x 0 If statementreturn statement xcondition left right a b operator > alternative … Figure 1: The procedure of extracting data flow given a source code. The graph in the rightmost is data flow that represents the relation of ”where-the-value-comes-from” between variables. Figure 1 shows the extraction of data flow through a source code. Given a source code C = {c1,c2,...,c n}, we first parse the code into an abstract syntax tree (AST) by a standard compiler tool2. The AST includes syntax information of the code and terminals (leaves) are used to identify the variable sequence, denoted as V = {v1,v2,...,v k}. We take each variable as a node of the graph and an direct edge ε= ⟨vi,vj⟩from vi to vj refers that the value of j-th variable comes from i-th variable. Taking x= expras an example, edges from all variables in exprto xare added into the graph. We denote the set of directed edges as E = {ε1,ε2,...,ε l}and the graph G(C) = (V,E) is data flow used to represent dependency relation between variables of the source code C. 4 G RAPH CODE BERT In this section, we describe GraphCodeBERT, a graph-based pre-trained model based on Transformer for programming language. We introduce model architecture, graph-guided masked attention and pre-training tasks including standard masked language model and newly introduced ones. More details about model pre-training setting are provided in the Appendix A. 2https://github.com/tree-sitter/tree-sitter 3 Published as a conference paper at ICLR 2021 Variable Sequence Value comes from … x=0 if b> a : x=b else …Return maximum value Text Code a 1 b 2 x 3 0 4 b 5 a 6 x 7 b 8 x 9 a 10 x 11 Source code Comment Return maximum value Data Flow [CLS] … x=0 if b> [MASK] : x=b else … [SEP]Return [MASK] value [SEP] a 1 b 2 x 3 0 4 b 5 a 6 x 7 b 8 x 9 a 10 x 11 … L1 L2 L12 GraphCodeBERT maximum a 1 2 4 5 6 8 10 data flow edge prediction among variables 7 9 113xx x variable-alignment across source code and data flow Masked Language Modeling 11 109 87 65 43 21 def max(a, b): x=0 if b>a: x=b else: x=a return x Figure 2: An illustration about GraphCodeBERT pre-training. The model takes source code paired with comment and the corresponding data flow as the input, and is pre-trained using standard masked language modeling (Devlin et al., 2018) and two structure-aware tasks. One structure-aware task is to predict where a variable is identified from (marked with orange lines) and the other is data flow edges prediction between variables (marked with blue lines). 4.1 M ODEL ARCHITECTURE Figure 2 shows the model architecture of GraphCodeBERT. We follow BERT (Devlin et al., 2018) and use the multi-layer bidirectional Transformer (Vaswani et al., 2017) as the model backbone. Instead of only using source code, we also utilize paired comments to pre-train the model to support more code-related tasks involving natural language such as natural language code search (Feng et al., 2020). We further take data flow, which is a graph, as a part of the input to the model. Given a source code C = {c1,c2,...,c n}with its comment W = {w1,w2,...,w m}, we can obtain the corresponding data flow G(C) = (V,E) as discussed in the Section 3, whereV = {v1,v2,...,v k} is a set of variables and E = {ε1,ε2,...,ε l}is a set of direct edges that represent where the value of each variable comes from. We concatenate the comment, source code and the set of variables as the sequence input X = {[CLS],W,[SEP],C, [SEP],V }, where [CLS] is a special token in front of three segments and [SEP] is a special symbol to split two kinds of data types. GraphCodeBERT takes the sequence Xas the input and then converts the sequence into input vectors H0. For each token, its input vector is constructed by summing the corresponding token and position embeddings. We use a special position embedding for all variables to indicate that they are nodes of data flow. The model applies N transformer layers over the input vectors to produce contextual representations Hn = transformern(Hn−1),n ∈[1,N]. Each transformer layer contains an architecturally identical transformer that applies a multi-headed self-attention operation (Vaswani et al., 2017) followed by a feed forward layer over the input Hn−1 in the n-th layer. Gn = LN(MultiAttn(Hn−1) +Hn−1) (1) Hn = LN(FFN (Gn) +Gn) (2) where MultiAttn is a multi-headed self-attention mechanism, FFN is a two layers feed forward network, and LN represents a layer normalization operation. For the n-th transformer layer, the output ˆGn of a multi-headed self-attention is computed via: Qi = Hn−1WQ i , Ki = Hn−1WK i , Vi = Hn−1WV i (3) headi = softmax(QiKT i√dk + M)Vi (4) ˆGn = [head1; ...; headu]WO n (5) where the previous layer’s outputHn−1 ∈R|X|×dh is linearly projected to a triplet of queries, keys and values using model parameters WQ i ,WK i ,WV i ∈Rdh×dk , respectively. uis the number of heads, dk is the dimension of a head, and WO n ∈Rdh×dh is the model parameters. M ∈R|X|×|X|is a mask matrix, where Mij is 0 if i-th token is allowed to attend j-th token otherwise −∞. 4 Published as a conference paper at ICLR 2021 4.2 G RAPH -GUIDED MASKED ATTENTION To incorporate the graph structure into Transformer, we define a graph-guided masked attention function to filter out irrelevant signals. The attention masking function could avoid the keyki attended by the query qj by adding the attention score qT j ki an infinitely negative value so that the attention weight becomes zero after using a softmax function. To represent dependency relation between variables, a node-query qvi is allowed to attend to a node-key kvj if there is a direct edge from the node vj to the node vi (i.e. ⟨vj,vi⟩∈ E) or they are the same node (i.e. i = j). Otherwise, the attention is masked by adding an infinitely negative value into the attention score. To represent the relation between source code tokens and nodes of the data flow, we first define a set E ′ , where ⟨vi,cj⟩/⟨cj,vi⟩∈ E ′ if the variable vi is identified from the source code token cj. We then allow the node qvi and code kcj attend each other if and only if ⟨vi,cj⟩/⟨cj,vi⟩∈ E ′ . More formally, we use the following graph-guided masked attention matrix as the mask matrix M in the equation 4: Mij = {0 if qi ∈{[CLS],[SEP]}or qi,kj ∈W ∪Cor ⟨qi,kj⟩∈ E∪E ′ −∞ otherwise (6) 4.3 P RE-TRAINING TASKS We describe three pre-training tasks used for pre-training GraphCodeBERT in this section. The first task is masked language modeling (Devlin et al., 2018) for learning representation from the source code. The second task is data flow edge prediction for learning representation from data flow, where we first mask some variables’ data flow edges and then let GraphCodeBERT predict those edges. The last task is variable-alignment across source code and data flow for aligning representation between source code and data flow, which predicts where a variable is identified from. Masked Language Modeling We follow Devlin et al. (2018) to apply masked language modeling (MLM) pre-training task. Specially, we sample randomly 15% of the tokens from the source code and paired comment. We replace them with a [MASK] token 80% of the time, with a random token 10% of the time, and leave them unchanged 10% of the time. The MLM objective is to predict original tokens of these sampled tokens, which has proven effective in previous works (Devlin et al., 2018; Liu et al., 2019; Feng et al., 2020). In particular, the model can leverage the comment context if the source code context is not sufficient to infer the masked code token, encouraging the model to align the natural language and programming language representations. Edge Prediction To learn representation from data flow, we introduce a pre-training task of data flow edges prediction. The motivation is to encourage the model to learn structure-aware repre- sentation that encodes the relation of “where-the-value-comes-from” for better code understanding. Specially, we randomly sample 20% of nodes Vs in data flow, mask direct edges connecting these sampled nodes by add an infinitely negative value in the mask matrix, and then predict these masked edges Emask. Taking the variable x11 in Figure 2 for an example, we first mask edges ⟨x7,x11⟩ and ⟨x9,x11⟩in the graph and then let the model to predict these edges. Formally, the pre-training objective of the task is calculated as Equation 7, where Ec = Vs ×V ∪V ×Vs is a set of candidates for edge prediction, δ(eij ∈E) is 1 if ⟨vi,vj⟩∈ Eotherwise 0, and the probability peij of existing an edge from i-th to j-th node is calculated by dot product following a sigmoid function using representations of two nodes from GraphCodeBERT. To balance positive-negative ratio of examples, we sample negative and positive samples with the same number for Ec. lossEdgePred = − ∑ eij∈Ec [δ(eij ∈Emask)logpeij + (1−δ(eij ∈Emask))log(1 −peij )] (7) Node Alignment To align representation between source code and data flow, we introduce a pre- training task of node alignment across source code and data flow, which is similar to data flow edge prediction. Instead of predicting edges between nodes, we predict edges between code tokens and nodes. The motivation is to encourage the model to align variables and source code according to data flow. Taking Figure 3 for an example, we first mask edges between the variable x11 in data flow and code tokens, and then predict which code token the variable x11 in data flow is identified from. As we can see, the model could predict that the variable x11 is identified form the variable xin the expression “return x” according to data flow information (i.e. the value ofx11 comes from x7 or x9). 5 Published as a conference paper at ICLR 2021 GraphCodeBERT Variable SequenceText Code [CLS] Return [MASK] value [SEP] def max ( a , b ) : x=0 if b>a : x=b else: x=a return x [SEP] 𝑎𝑎1 𝑏𝑏2 𝑥𝑥3 04 𝑏𝑏5 𝑎𝑎6 𝑥𝑥7 𝑏𝑏8 𝑥𝑥9 𝑎𝑎10 𝑥𝑥11 Predict which code token the variable 𝑥𝑥11 in data flow is identified from Mask edges between the variable 𝑥𝑥11 in data flow and code tokens Figure 3: An example of the Node Alignment task. Specially, we randomly sample 20% nodes V ′ s in the graph, mask edges between code tokens and sampled nodes, and then predict masked edges E ′ mask. The pre-training objective of this task is similar to Equation 7, where E ′ c = V ′ s ×Cis a set of candidates for node alignment. Similarly, we also sample negative and positive samples with the same number for E ′ c. lossNodeAlign = − ∑ eij∈E′ c [δ(eij ∈E ′ mask)logpeij + (1−δ(eij ∈E ′ mask))log(1 −peij )] (8) 5 E XPERIMENTS We evaluate our model on four downstream tasks, including code search, clone detection, code translation and code refinement. Detailed experimental settings can be found in the Appendix. 5.1 N ATURAL LANGUAGE CODE SEARCH Given a natural language as the input, the task aims to find the most semantically related code from a collection of candidate codes. We conduct experiments on the CodeSearchNet code corpus (Husain et al., 2019), which includes six programming languages. Different from the dataset and the setting used in the Husain et al. (2019), we filter low-quality queries by handcrafted rules and expand 1000 candidates to the whole code corpus, which is closer to the real-life scenario. We use Mean Reciprocal Rank (MRR) as our evaluation metric and report results of existing methods in the Table 1. We provide more details about the filtered dataset and also give results using the same setting of Husain et al. (2019) in the Appendix B. model Ruby Javascript Go Python Java Php Overall NBow 0.162 0.157 0.330 0.161 0.171 0.152 0.189 CNN 0.276 0.224 0.680 0.242 0.263 0.260 0.324 BiRNN 0.213 0.193 0.688 0.290 0.304 0.338 0.338 selfAtt 0.275 0.287 0.723 0.398 0.404 0.426 0.419 RoBERTa 0.587 0.517 0.850 0.587 0.599 0.560 0.617 RoBERTa (code) 0.628 0.562 0.859 0.610 0.620 0.579 0.643 CodeBERT 0.679 0.620 0.882 0.672 0.676 0.628 0.693 GraphCodeBERT 0.703 0.644 0.897 0.692 0.691 0.649 0.713 Table 1: Results on code search. GraphCodeBERT outperforms other models significantly (p< 0.01). All models calculate inner product of code and query encodings as relevance scores to rank candidate codes. We follow Husain et al. (2019) to implement four methods as baselines in the first group to obtain the encodings, including bag-of-words, convolutional neural network, bidirectional recurrent neural network, and multi-head attention. The second group is the results of pre-trained models. Roberta (Liu et al., 2019) is a pre-trained model on text corpus with MLM learning objective, while RoBERTa (code)is pre-trained only on code. CodeBERT (Feng et al., 2020) is pre-trained 6 Published as a conference paper at ICLR 2021 on code-text pairs with MLM and replaced token detection learning objectives. As we can see, GraphCodeBERT that leverages code structure for pre-training brings a 2% gain of MRR, achieving the state-of-art performance. We also conducted t-test between our GraphCodeBERT and other baselines, and the results show the improvements are significant with p< 0.01. 5.2 C ODE CLONE DETECTION Code clones are multiple code fragments that output similar results when given the same input. The task aims to measure the similarity between two code fragments, which can help reduce the cost of software maintenance and prevent bugs. We conduct experiments on the BigCloneBench dataset (Svajlenko et al., 2014) and report results in the Table 2. Deckard (Jiang et al., 2007) is to compute vectors for structural information within ASTs and then a Locality Sensitive Hashing (LSH) (Datar et al., 2004) is used to cluster similar vectors for detection. RtvNN (White et al., 2016) trains a recursive autoencoder to learn representations for AST. CDLH (Wei & Li, 2017) learn representations of code fragments via AST-based LSTM and hamming distance is used to optimize the distance between the vector representation of AST pairs. Model Precision Recall F1 Deckard 0.93 0.02 0.03 RtvNN 0.95 0.01 0.01 CDLH 0.92 0.74 0.82 ASTNN 0.92 0.94 0.93 FA-AST-GMN 0.96 0.94 0.95 RoBERTa (code) 0.949 0.922 0.935 CodeBERT 0.947 0.934 0.941 GraphCodeBERT 0.948 0.952 0.950 Table 2: Results on code clone detection. Graph- CodeBERT outperforms other pre-trained methods significantly (p< 0.01). ASTNN Zhang et al. (2019) uses RNNs to encode AST subtrees for statements, then feed the encodings of all statement trees into an RNN to learn representation for a pro- gram. FA-AST-GMN (Wang et al., 2020) uses GNNs over a flow-augmented AST to leverages explicit control and data flow in- formation for code clone detection. Results show that our GraphCodeBERT that lever- ages code structure information significantly outperforms other methods with p < 0.01, which demonstrates the effectiveness of our pre-trained model for the task of code clone detection. 5.3 C ODE TRANSLATION Code translation aims to migrate legacy software from one programming language in a platform to another. Following Nguyen et al. (2015) and Chen et al. (2018), we conduct experiments on a dataset crawled from the same several open-source projects as them and report results in the Table 3. The Naive method is directly copying the source code as the translation result. PBSMT is short for phrase-based statistical machine translation (Koehn et al., 2003), and has been exploited in previous works (Nguyen et al., 2013; Karaivanov et al., 2014). As for the Transformer, we use the Method Java→C# C#→Java BLEU Acc BLEU Acc Naive 18.54 0.0 18.69 0.0 PBSMT 43.53 12.5 40.06 16.1 Transformer 55.84 33.0 50.47 37.9 RoBERTa (code) 77.46 56.1 71.99 57.9 CodeBERT 79.92 59.0 72.14 58.8 GraphCodeBERT 80.58 59.4 72.64 58.8 Table 3: Results on code translation. same number of layers and hidden size as pre-trained models. To leverage the pre-trained models for translation, we ini- tialize the encoder with pre-trained mod- els and randomly initialize parameters of the decoder and the source-to-target atten- tion. Results show that the models initial- ized with pre-trained models (i.e the second group) outperform PBSMT and Transformer models. Among them, GraphCodeBERT achieves state-of-art performance, which demonstrates the effectiveness of our model for code translation. 5.4 C ODE REFINEMENT Code refinement aims to automatically fix bugs in the code, which can contribute to reducing the cost of bug-fixes. We use the dataset released by Tufano et al. (2019) and report results in the Table 4. 7 Published as a conference paper at ICLR 2021 The Naive method directly copies the buggy code as the refinement result. For the Transformer, we use the same number of layers and hidden size as the pre-trained models. Same as the Section 5.3, we initialize the encoder with pre-trained models and randomly initialize parameters of the decoder Method small medium BLEU Acc BLEU Acc Naive 78.06 0.0 90.91 0.0 LSTM 76.76 10.0 72.08 2.5 Transformer 77.21 14.7 89.25 3.7 RoBERTa (code) 77.30 15.9 90.07 4.1 CodeBERT 77.42 16.4 91.07 5.2 GraphCodeBERT 80.02 17.3 91.31 9.1 Table 4: Results on code refinement. and the source-to-target attention. Then we use the training data to fine-tune the whole model. In the table, we see that the Transformer significantly out- performs LSTM. Results in the second group shows that pre-trained models out- perform Transformer models further, and GraphCodeBERT achieves better per- formance than other pre-trained models on both datasets, which shows leveraging code structure information are helpful to the task of code refinement. 5.5 M ODEL ANALYSIS Ablation Study We conduct ablation study on the task of natural language code search to under- stand various components in our approach impact overall performance. We remove two pre-training tasks and data flow, respectively, to analyze their contribution. Table 5 shows that the overall perfor- mance drops from 71.3% to 70.3%∼70.7% when removing Node Alignment and Edge Prediction pre-training tasks, respectively, which reveals the importance of two structure-aware pre-training tasks. After ablating the data flow totally, we can see that the performance drops from 71.3% to 69.3%, which means leveraging data flow to learn code representation could improve GraphCodeBERT. Methods Ruby Javascript Go Python Java Php Overall GraphCodeBERT 0.703 0.644 0.897 0.692 0.691 0.649 0.713 -w/o EdgePred 0.701 0.632 0.894 0.687 0.688 0.640 0.707 -w/o NodeAlign 0.685 0.635 0.887 0.682 0.690 0.640 0.703 -w/o Data Flow 0.679 0.620 0.882 0.672 0.676 0.628 0.693 Table 5: Ablation study on natural language code search Node-vs. Token-level Attention Table 6 shows how frequently a special token [CLS] that is used to calculate probability of correct candidate attends to code tokens (Codes) and variables (Nodes). We see that although the number of nodes account for 5%∼20%, attentions over nodes overwhelm node/code ratio (around 10% to 32%) across all programming languages. The results indicate that data flow plays an important role in code understanding process and the model pays more attention to nodes in data flow than code tokens. Ruby Javascript Go Python Java Php Codes/Nodes 90.1/9.9 94.6/5.4 95.0/5.03 80.6/19.4 93.2/6.8 87.5/12.5 [CLS] →Codes/Nodes 82.3/17.7 89.7/10.3 91.0/9.0 67.7/32.3 87.8/12.2 79.4/20.6 Table 6: Attention distribution (%) between code tokens (codes) and variables (nodes) across different programming language on natural language code search test sets. The first row is the ratio of the number of code tokens to nodes, and the second row is attention distribution of [CLS] token. Comparison between AST and Data FlowFigure 4 shows MRR score with respect to input sequence length on the validation dataset of Ruby programming language for the task of code search. AST Pre-order Traversalregards AST as a sequence by linearizing all AST nodes us- ing pre-order traversal algorithm. AST Subtree Maskingregards AST as a tree and introduce subtree masking (Nguyen et al., 2019) for self-attention of the Transformer. In subtree masking, each node-query in AST attends only to its own subtree descendants, and each leaf-query only attends to leaves of AST. Transformer has a self-attention component withO(n2) time and memory complexity where nis the input sequence length, and thus is not efficient to scale to long inputs. 8 Published as a conference paper at ICLR 2021 64 96 128 192 256 512 Sequence Length 0.60 0.62 0.64 0.66 0.68 0.70 0.72 0.74 0.76MRR Score w/o code structure AST Pre-order Traversal AST Subtree Masking GraphCodeBERT Figure 4: MRR score on the validation dataset of Ruby for code search with varying length of input sequence. We observe that injecting AST even hurts the performance when the sequence length is short (e.g. shorter than 128), while Graph- CodeBERT consistently brings performance boost on varying se- quence length and obtains better MRR score than AST-based meth- ods. The main reason is that data flow is less complex and the num- ber of nodes account for 5% ∼ 20% (see Table 6), which does not bring an unnecessarily deep hierar- chy of AST and makes the model more accurate and efficient. Case Study We also give a case study to demonstrate that data flow would enhance the code understanding process. Given a source code and a comment, we use GraphCodeBERT with and without data flow to predict whether the comment correctly describes the source code. Results are given in Figure 5. We can see that both models make correct prediction in the original example, where the threshold is 0.5 (left panel). To study the code understanding ability of models, we change the source code (center panel) and the comment (right panel), respectively. Although we make a small change on the source code (returna →returnb) and the comment (sumvalue →meanvalue), the semantic of the source code and the comment are completely different and corresponding gold labels change from 1 to 0. As we can see in the figure, GraphCodeBERT without using data flow fails these tests and still outputs high probability for negative examples. After leveraging data flow, GraphCodeBERT better understands the semantic of source code and makes correct predictions on all tests, which demonstrates that data flow could improve the code understanding ability of the model. Unchanged Code: 𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑎𝑎 → 𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑟𝑏𝑏 NL: 𝑠𝑠𝑟𝑟𝑠𝑠𝑣𝑣𝑎𝑎𝑣𝑣𝑟𝑟𝑟𝑟 → 𝑠𝑠𝑟𝑟𝑎𝑎𝑟𝑟𝑣𝑣𝑎𝑎𝑣𝑣𝑟𝑟𝑟𝑟 Input Label 1 0 0 Prediction GraphCodeBERT: 0.6563 (1) GraphCodeBERT: 0.8728 (1) (w/o Data Flow) GraphCodeBERT: 0.4615 (0) GraphCodeBERT: 0.8608 (1) (w/o Data Flow) GraphCodeBERT: 0.2884 (0) GraphCodeBERT: 0.9048 (1) (w/o Data Flow) NL: Return sum value of an array Code: import numpy as np def f(array): a=np.sum(array) b=np.mean(array) return a NL: Return sum value of an array Code: import numpy as np def f(array): a=np.sum(array) b=np.mean(array) return b NL: Return mean value of an array Code: import numpy as np def f(array): a=np.sum(array) b=np.mean(array) return a Figure 5: We take a comment and a source code as the input (first row), and use GraphCodeBERT with and without data flow to predict the probability of the source code matching the comment (third row). The label is 1 if the comment correctly describes the source code otherwise 0 (second row). 6 C ONCLUSION In this paper, we present GraphCodeBERT that leverages data flow to learn code representation. To the best of our knowledge, this is the first pre-trained model that considers code structure for pre-training code representations. We introduce two structure-aware pre-training tasks and show that GraphCodeBERT achieves state-of-the-art performance on four code-related downstream tasks, including code search, clone detection, code translation and code refinement. Further analysis shows that code structure and newly introduced pre-training tasks boost the performance. Additionally, case study in the task of code search shows that applying data flow in the pre-trained model improves code understanding. 9 Published as a conference paper at ICLR 2021 ACKNOWLEDGMENTS Daya Guo and Jian Yin are supported by the Research Foundation of Science and Technology Plan Project in Guangdong Province (2017B030308007). REFERENCES Miltiadis Allamanis, Marc Brockschmidt, and Mahmoud Khademi. Learning to represent programs with graphs. In International Conference on Learning Representations, 2018. Uri Alon, Shaked Brody, Omer Levy, and Eran Yahav. code2seq: Generating sequences from structured representations of code. arXiv preprint arXiv:1808.01400, 2018. Uri Alon, Roy Sadaka, Omer Levy, and Eran Yahav. Structural language models of code. arXiv, pp. arXiv–1910, 2019. Marc Brockschmidt, Miltiadis Allamanis, Alexander L Gaunt, and Oleksandr Polozov. Generative code modeling with graphs. arXiv preprint arXiv:1805.08490, 2018. Luca Buratti, Saurabh Pujar, Mihaela Bornea, Scott McCarley, Yunhui Zheng, Gaetano Rossiello, Alessandro Morari, Jim Laredo, Veronika Thost, Yufan Zhuang, et al. Exploring software natural- ness throughneural language models. arXiv preprint arXiv:2006.12641, 2020. Xinyun Chen, Chang Liu, and Dawn Song. Tree-to-tree neural networks for program translation. In Advances in neural information processing systems, pp. 2547–2557, 2018. Mayur Datar, Nicole Immorlica, Piotr Indyk, and Vahab S Mirrokni. Locality-sensitive hashing scheme based on p-stable distributions. In Proceedings of the twentieth annual symposium on Computational geometry, pp. 253–262, 2004. Jacob Devlin, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. Bert: Pre-training of deep bidirectional transformers for language understanding. arXiv preprint arXiv:1810.04805, 2018. Zhangyin Feng, Daya Guo, Duyu Tang, Nan Duan, Xiaocheng Feng, Ming Gong, Linjun Shou, Bing Qin, Ting Liu, Daxin Jiang, et al. Codebert: A pre-trained model for programming and natural languages. arXiv preprint arXiv:2002.08155, 2020. Daya Guo, Duyu Tang, Nan Duan, M. Zhou, and Jian Yin. Dialog-to-action: Conversational question answering over a large-scale knowledge base. In NeurIPS, 2018. Daya Guo, Duyu Tang, Nan Duan, M. Zhou, and Jian Yin. Coupling retrieval and meta-learning for context-dependent semantic parsing. ArXiv, abs/1906.07108, 2019. Vincent J Hellendoorn, Charles Sutton, Rishabh Singh, Petros Maniatis, and David Bieber. Global relational models of source code. In International Conference on Learning Representations, 2019. Xing Hu, Ge Li, Xin Xia, David Lo, and Zhi Jin. Deep code comment generation. In2018 IEEE/ACM 26th International Conference on Program Comprehension (ICPC), pp. 200–20010. IEEE, 2018. Hamel Husain, Ho-Hsiang Wu, Tiferet Gazit, Miltiadis Allamanis, and Marc Brockschmidt. Code- searchnet challenge: Evaluating the state of semantic code search.arXiv preprint arXiv:1909.09436, 2019. Lingxiao Jiang, Ghassan Misherghi, Zhendong Su, and Stephane Glondu. Deckard: Scalable and accurate tree-based detection of code clones. In 29th International Conference on Software Engineering (ICSE’07), pp. 96–105. IEEE, 2007. Aditya Kanade, Petros Maniatis, Gogul Balakrishnan, and Kensen Shi. Pre-trained contextual embedding of source code. arXiv preprint arXiv:2001.00059, 2019. Svetoslav Karaivanov, Veselin Raychev, and Martin Vechev. Phrase-based statistical translation of programming languages. In Proceedings of the 2014 ACM International Symposium on New Ideas, New Paradigms, and Reflections on Programming & Software, pp. 173–184, 2014. 10 Published as a conference paper at ICLR 2021 Rafael-Michael Karampatsis and Charles Sutton. Scelmo: Source code embeddings from language models. arXiv preprint arXiv:2004.13214, 2020. Seohyun Kim, Jinman Zhao, Yuchi Tian, and Satish Chandra. Code prediction by feeding trees to transformers. arXiv preprint arXiv:2003.13848, 2020. Philipp Koehn, Franz J Och, and Daniel Marcu. Statistical phrase-based translation. Technical report, UNIVERSITY OF SOUTHERN CALIFORNIA MARINA DEL REY INFORMATION SCIENCES INST, 2003. Guillaume Lample and Alexis Conneau. Cross-lingual language model pretraining. arXiv preprint arXiv:1901.07291, 2019. Jian Li, Yue Wang, Michael R Lyu, and Irwin King. Code completion with neural attention and pointer networks. arXiv preprint arXiv:1711.09573, 2017. Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Mandar Joshi, Danqi Chen, Omer Levy, Mike Lewis, Luke Zettlemoyer, and Veselin Stoyanov. Roberta: A robustly optimized bert pretraining approach. arXiv preprint arXiv:1907.11692, 2019. Anh Tuan Nguyen and Tien N Nguyen. Graph-based statistical language model for code. In 2015 IEEE/ACM 37th IEEE International Conference on Software Engineering, volume 1, pp. 858–868. IEEE, 2015. Anh Tuan Nguyen, Tung Thanh Nguyen, and Tien N Nguyen. Lexical statistical machine translation for language migration. In Proceedings of the 2013 9th Joint Meeting on Foundations of Software Engineering, pp. 651–654, 2013. Anh Tuan Nguyen, Tung Thanh Nguyen, and Tien N Nguyen. Divide-and-conquer approach for multi-phase statistical migration for source code (t). In 2015 30th IEEE/ACM International Conference on Automated Software Engineering (ASE), pp. 585–596. IEEE, 2015. Xuan-Phi Nguyen, Shafiq Joty, Steven Hoi, and Richard Socher. Tree-structured attention with hierarchical accumulation. In International Conference on Learning Representations, 2019. Matthew E Peters, Mark Neumann, Mohit Iyyer, Matt Gardner, Christopher Clark, Kenton Lee, and Luke Zettlemoyer. Deep contextualized word representations. arXiv preprint arXiv:1802.05365, 2018. Maxim Rabinovich, Mitchell Stern, and Dan Klein. Abstract syntax networks for code generation and semantic parsing. arXiv preprint arXiv:1704.07535, 2017. Alec Radford, Karthik Narasimhan, Tim Salimans, and Ilya Sutskever. Improving language understanding by generative pre-training. URL https://s3-us-west-2. amazonaws. com/openai- assets/researchcovers/languageunsupervised/language understanding paper. pdf, 2018. Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, and Peter J Liu. Exploring the limits of transfer learning with a unified text-to-text transformer. arXiv preprint arXiv:1910.10683, 2019. Jeffrey Svajlenko, Judith F Islam, Iman Keivanloo, Chanchal K Roy, and Mohammad Mamun Mia. Towards a big data curated benchmark of inter-project code clones. In 2014 IEEE International Conference on Software Maintenance and Evolution, pp. 476–480. IEEE, 2014. Alexey Svyatkovskiy, Shao Kun Deng, Shengyu Fu, and Neel Sundaresan. Intellicode compose: Code generation using transformer. arXiv preprint arXiv:2005.08025, 2020. Michele Tufano, Cody Watson, Gabriele Bavota, Massimiliano Di Penta, Martin White, and Denys Poshyvanyk. An empirical study on learning bug-fixing patches in the wild via neural machine translation. ACM Transactions on Software Engineering and Methodology (TOSEM), 28(4):1–29, 2019. Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N Gomez,Łukasz Kaiser, and Illia Polosukhin. Attention is all you need. In Advances in neural information processing systems, pp. 5998–6008, 2017. 11 Published as a conference paper at ICLR 2021 Wenhan Wang, Ge Li, Bo Ma, Xin Xia, and Zhi Jin. Detecting code clones with graph neural networkand flow-augmented abstract syntax tree. arXiv preprint arXiv:2002.08653, 2020. Huihui Wei and Ming Li. Supervised deep features for software functional clone detection by exploiting lexical and syntactical information in source code. In IJCAI, pp. 3034–3040, 2017. Martin White, Michele Tufano, Christopher Vendome, and Denys Poshyvanyk. Deep learning code fragments for code clone detection. In 2016 31st IEEE/ACM International Conference on Automated Software Engineering (ASE), pp. 87–98. IEEE, 2016. Zhilin Yang, Zihang Dai, Yiming Yang, Jaime Carbonell, Ruslan Salakhutdinov, and Quoc V Le. Xlnet: Generalized autoregressive pretraining for language understanding. arXiv preprint arXiv:1906.08237, 2019. Pengcheng Yin and Graham Neubig. A syntactic neural model for general-purpose code generation. In The 55th Annual Meeting of the Association for Computational Linguistics (ACL), Vancouver, Canada, July 2017. URL https://arxiv.org/abs/1704.01696. Jian Zhang, Xu Wang, Hongyu Zhang, Hailong Sun, Kaixuan Wang, and Xudong Liu. A novel neural source code representation based on abstract syntax tree. In 2019 IEEE/ACM 41st International Conference on Software Engineering (ICSE), pp. 783–794. IEEE, 2019. A P RE-TRAINING DETAILS GraphCodeBERT includes 12 layers Transformer with 768 dimensional hidden states and 12 attention heads. For fair comparison, we use the same dataset as CodeBERT (Feng et al., 2020) to pretrain our model. The dataset is the CodeSearchNet dataset3 (Husain et al., 2019), which includes 2.3M functions with document pairs for six programming languages. We train the model on two DGX-2 machines, each having 16 NVIDIA Tesla V100 with 32GB memory. We set the max length of sequences and nodes as 512 and 128, respectively. We use the Adam optimizer to update model parameters with 1,024 batch size and 2e-4 learning rate. To accelerate the training process, we adopt the parameters of CodeBERT released by Feng et al. (2020) to initialize the model. The model is trained with 200K batches and costs about 83 hours. At each iteration, we alternate EdgePred and NodeAlign objectives in combination with MLM to pre-train the model. And we follow Lample & Conneau (2019) to sample each batch from the same programming language according to a multinomial distribution with probabilities {qi}i=1...N, where ni is number of examples for i-th programming language and α=0.7. Sampling with this distribution could alleviates the bias towards high-resource languages. qi = pα i∑j=1 N pα j with pi = ni ∑k=1 N nk (9) B N ATURAL LANGUAGE CODE SEARCH Given a natural language as the input, code search aims to find the most semantically related code from a collection of candidate codes. We conduct experiments on the CodeSearchNet code corpus (Husain et al., 2019) and follow Husain et al. (2019) to take the first paragraph of the documentation as the query for the corresponding function. However, we observe that some queries contain content unrelated to the code, such as a link “http://...” that refers to external resources. Therefore, we filter following examples to improve the quality of the dataset. (1) Examples whose code could not be parsed into abstract syntax tree. (2) Examples whose query tokens number is shorter than 3 or larger than 256. (3) Examples whose query contains special tokens such as “http://”. (4) Examples whose query is empty or not written in English. 3https://github.com/github/CodeSearchNet 12 Published as a conference paper at ICLR 2021 Different from the setting of Husain et al. (2019), the answer of each query is retrieved from the whole development and testing code corpus instead of 1,000 candidate codes. We list data statistics about the filtered dataset in Table 7. Code Search Training examples Dev queries Testing queries Candidate codes Go 167,288 7,325 8,122 28,120 Java 164,923 5,183 10,955 40,347 JavaScript 58,025 3,885 3,291 13,981 PHP 241,241 12,982 14,014 52,660 Python 251,820 13,914 14,918 43,827 Ruby 24,927 1,400 1,261 4,360 Table 7: Data statistics about the filtered dataset. For each query in the development and testing sets, the answer is retrieved from the whole candidate codes (i.e. the last row). We use GraphCodeBERT to separately encode query and source code with data flow, and calculate inner product of their representations of the special token[CLS] as relevance scores to rank candidate codes. In the fine-turning step, we set the learning rate as 2e-5, the batch size as 32, the max sequence length of queries and codes as 128 and 256, and the max number of nodes as 64. We use the Adam optimizer to update model parameters and perform early stopping on the development set. We also report the results using the same setting of Husain et al. (2019) in Table 8. In this setting, models are required to retrieve an answer for a query from 1000 candidates. The results show that GraphCodeBERT also achieves the state-of-the-art performance. model Ruby Javascript Go Python Java Php Overall NBow 0.429 0.461 0.641 0.581 0.514 0.484 0.518 CNN 0.245 0.352 0.627 0.571 0.527 0.529 0.475 BiRNN 0.084 0.153 0.452 0.321 0.287 0.251 0.258 selfAtt 0.365 0.451 0.681 0.692 0.587 0.601 0.563 RoBERTa 0.625 0.606 0.820 0.809 0.666 0.658 0.697 RoBERTa (code) 0.661 0.640 0.819 0.844 0.721 0.671 0.726 CodeBERT 0.693 0.706 0.840 0.869 0.748 0.706 0.760 GraphCodeBERT 0.732 0.711 0.841 0.879 0.757 0.725 0.774 Table 8: Results on natural language code search using the setting of Husain et al. (2019). C C ODE CLONE DETECTION Code clone detection aims to measure the similarity between two code fragments. We use Big- CloneBench dataset (Svajlenko et al., 2014), which contains over 6,000,000 true clone pairs and 260,000 false clone pairs from 10 different functionalities. We follow the settings in Wei & Li (2017), discarding code fragments without any tagged true and false clone pairs and using 9,134 remaining code fragments. Finally, the dataset provided by Wang et al. (2020) includes 901,724/416,328/416,328 examples for training/validation/testing. We treat the task as a binary classification to fine-tune Graph- CodeBERT, where we use source code and data flow as the input. The probability of true clone is calculated by dot product from the representation of [CLS]. In the fine-turning step, we set the learning rate as 2e-5, the batch size as 16, the max sequence length as 512 the max number of nodes as 128. We use the Adam optimizer to update model parameters and tune hyper-parameters and perform early stopping on the development set. We give a case of the GraphCodeBERT output for this task in Figure 6. In this example, two Java source codes both download content from a given URL and convert the type of the content into string type. Therefore, two codes are semantically similar since they output similar results when given the same input. As we can see, our model gives a high score for this case and the pair is classified as true clone pair. 13 Published as a conference paper at ICLR 2021 protected String downloadURLtoString(URL url) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); StringBuffer sb = new StringBuffer(100 * 1024); String str; while ((str = in.readLine()) != null) { sb.append(str); } in.close(); return sb.toString(); } public static String fetchUrl(String urlString) { try { URL url = new URL(urlString); BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); String line = null; StringBuilder builder = new StringBuilder(); while ((line = reader.readLine()) != null) { builder.append(line); } reader.close(); return builder.toString(); } catch (MalformedURLException e) { } catch (IOException e) { } return “"; } Input: Two source codes Output: Semantically similar (score: 0.983) Figure 6: A case of GraphCodeBERT output for the code clone detection task. D C ODE TRANSLATION Code translation aims to migrate legacy software from one programming language in a platform to another. We conduct experiments on a dataset crawled from the same several open-source projects as Nguyen et al. (2015) and Chen et al. (2018), i.e. Lucene 4, POI5, JGit6 and Antlr7. We do not use Itext8 and JTS9 as they do because of the license problem. Those projects have both Java and C# implementation. We pair the methods in the two languages based on their file names and method names. After removing duplication and methods with null function body, the total number of method pairs is 11,800, and we split 500 pairs from them as the development set and another 1,000 pairs for test. To demonstrate the effectiveness of GraphCodeBERT on the task of code translation, we adopt various pre-trained models as encoders and stay hyperparameters consistent. We set the learning rate as 1e-4, the batch size as 32, the max sequence length as 256 and the max number of nodes as 64. We use the Adam optimizer to update model parameters and tune hyper-parameters and perform early stopping on the development set. We give a case of the GraphCodeBERT output for this task in Figure 7. In this example, the model successfully translates a piece of Java code into its C# version. The differences include the type name (from “boolean” to “bool”) and the usage of getting a string value of a bool variable (from “String.valueOf(b)” to “b.ToString()”). Figure 7: A case of GraphCodeBERT output for the code translation task. 4http://lucene.apache.org/ 5http://poi.apache.org/ 6https://github.com/eclipse/jgit/ 7https://github.com/antlr/ 8http://sourceforge.net/projects/itext/ 9http://sourceforge.net/projects/jts-topo-suite/ 14 Published as a conference paper at ICLR 2021 E C ODE REFINEMENT Code refinement aims to automatically fix bugs in the code. We use the dataset released by Tufano et al. (2019). The source is buggy Java functions while the target is the according fixed ones. Almost all the names of variables and custom methods are normalized. The dataset contains two subsets based on the code length. For the small dataset, the numbers of training, development and test samples are 46,680, 5,835 and 5,835. For the medium dataset, the numbers are 52,364, 6,545 and 6,545. We also use the sequence-to-sequence Transformer model to conduct the experiments. In the fine-tuning step, we adopt various pre-trained models as encoders. We set the learning rate as 1e-4, the batch size as 32, the max sequence length as 256 and the max number of nodes as 64. We use the Adam optimizer to update model parameters and perform early stopping on the development set. We give two cases of the GraphCodeBERT output for this task in Figure 8. In the first example, the model successfully fixes the operation bug (from “*” to “+”) to match the function name “add”. In the second case, the source function and type names are normalized. The return type of this function is “void” but the buggy code gives a return value. Our model successfully removes the “return” word so that the return type of the function matches its declaration. Figure 8: Two cases of GraphCodeBERT output for the code refinement task. F C ASE STUDY F.1 N ATURAL LANGUAGE CODE SEARCH We give a case study to illustrate retrieved results by GraphCodeBERT on the natural language code search task, with a comparison to CodeBERT and RoBERTa (code) models. Two examples are given in Figure 9 and we can see that GraphCodeBERT successfully retrieves correct source codes for given queries on both examples. As we can see in the first case, incorporating data flow will help Graph-CodeBERT better understand the complicated expression “[(k, v) for k, v in self.items() if v is not self.EMPTY]” by leveraging dependency relation among variables in data flow graph. In the second case, the terminology “%Y-%m-%d” in Python program language is a format of date time. GraphCodeBERT and CodeBERT both successfully search the correct function. Compared with RoBERTa (code), the second case shows that utilizing natural language descriptions for pre-training helps models do better semantic matching between source codes and queries on the code search task. F.2 C ODE CLONE DETECTION We give a case study to compare GraphCodeBERT with CodeBERT and RoBERTa (code) models on code clone detection task. An example is shown in Figure 10. The first source code is to return the HTML content from a given URL, while the second source code is to return the last line from a fixed URL “http://kmttg.googlecode.com/svn/trunk/version”. Their semantics are not similar due to their different outputs. Data flow could help GraphCodeBERT better understand that the return value “pageHTML” in first source code comes from “pageHTML.append(line); pageHTML.append(“\r\n”);” instead of “bufferedWriter.write(pageHTML.toString());” and the return value “version” in the second source code comes from “version = inputLine” or “version = null;”. Although two source codes are highly overlapped (marked in yellow), GraphCodeBERT successfully predict the gold label compared with other models without data flow. 15 Published as a conference paper at ICLR 2021 Case 1 Query: Return copy of instance, omitting entries that are EMPTY Gold Source Code: def defined_items(self): return self.__class__( [(k, v) for k, v in self.items() if v is not self.EMPTY], is_empty=False ) Search Results (Top1) GraphCodeBERT: def defined_items(self): return self.__class__( [(k, v) for k, v in self.items() if v is not self.EMPTY], is_empty=False ) CodeBERT: def copy(self): context = CLIContext() for item in dir(self): if item[0] != '_' and item not in ('copy', 'write_headers’): setattr(context, item, getattr(self, item)) return context RoBERTa(code): def copy(self): x = self.to_dict() x.pop(self._pkey) return self.__class__(**x) Case 2 Query: Fast %Y-%m-%d parsing Gold Source Code: def parse_date(s): try: return datetime.date(int(s[:4]), int(s[5:7]), int(s[8:10])) except ValueError: return datetime.datetime.strptime(s, '%d %B %Y').date() Search Results (Top1) GraphCodeBERT: def parse_date(s): try: return datetime.date(int(s[:4]), int(s[5:7]), int(s[8:10])) except ValueError: return datetime.datetime.strptime(s, '%d %B %Y').date() CodeBERT: def parse_date(s): try: return datetime.date(int(s[:4]), int(s[5:7]), int(s[8:10])) except ValueError: return datetime.datetime.strptime(s, '%d %B %Y').date() RoBERTa(code): def parse(self, hcl, canonicalize=False): return self.request("parse", json={"JobHCL": hcl, "Canonicalize": canonicalize}, method="post", allow_redirects=True).json() Figure 9: Two examples on code search task and retrieved results from different models. Source code 1: private String getHTML(String pageURL, String encoding, String dirPath) throws IOException { StringBuilder pageHTML = new StringBuilder(); HttpURLConnection connection = null; try { URL url = new URL(pageURL); connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("User-Agent", "MSIE 7.0"); connection.connect(); BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding)); String line = null; while ((line = br.readLine()) != null) { pageHTML.append(line); pageHTML.append("\r\n"); } } catch (Exception e) { e.printStackTrace(); } finally { connection.disconnect(); } if (dirPath != null) { File file = new File(dirPath); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file)); bufferedWriter.write(pageHTML.toString()); bufferedWriter.close(); } return pageHTML.toString(); } Source code 2: private static String getVersion() { debug.print(""); String version = null; String version_url = "http://kmttg.googlecode.com/svn/trunk/version"; try { URL url = new URL(version_url); URLConnection con = url.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) version = inputLine; in.close(); } catch (Exception ex) { version = null; } return version; } Gold Label: No semantically similar Prediction: GraphCodeBERT: No semantically similar CodeBERT: semantically similar RoBERTa(code): semantically similar Figure 10: An examples on code clone detection task and model prediction from different models. Overlapped code snippets between two source codes are marked in yellow. F.3 C ODE TRANSLATION AND CODE REFINEMENT We give a case study to compare GraphCodeBERT with Transformer without using data flow on code generation tasks, including code translation and code refinement. We list three cases in Table 9 and Table 10, respectively. [src] represents the source input, [ref] represents the reference, [sys] represents Transformer without data flow and [ours] represents GraphCodeBERT. We can see that the Transformer ([sys]) baseline makes several mistakes, including repeating tokens, logic errors and syntax errors, while GraphCodeBERT ([ours]) as a encoder could improve the generation. 16 Published as a conference paper at ICLR 2021 Case1: Transformer outputs repeating tokens [src] public static final WeightedTerm[] getTerms(Query query){return getTerms(query,false);} [ref] public static WeightedTerm[] GetTerms(Query query){return GetTerms(query, false);} [sys] public static WeightedTerm[] GetTerms(Query query){return GetTerms(false, new static static static static static static WeightTerms);} [ours] public static WeightedTerm[] GetTerms(Query query){return GetTerms(query, false);} Case2: Transformer outputs codes with severe logic and syntax errors [src] public long skip(long n){int s = (int) Math.min(available(), Math.max(0, n));ptr += s;return s;} [ref] public override long Skip(long n){int s = (int)Math.Min(Available(), Math.Max(0, n)); ptr += s;return s;} [sys] public override long Skip(long n){int s = Math.Min(n) == 0 ? Math.Min(00.0 : Math.Min(n, s.Length);return s;} [ours] public override long Skip(long n){int s = (int)Math.Min(Available(), Math.Max(0, n)); ptr += s;return s;} Case3: Transformer uses the wrong variable as a parameter. [src] public UnbufferedCharStream(int bufferSize){n = 0;data = new int[bufferSize];} [ref] public UnbufferedCharStream(int bufferSize){n = 0;data = new int[bufferSize];} [sys] public UnbufferedCharStream(int bufferSize){data = new int[data];} [ours] public UnbufferedCharStream(int bufferSize){n = 0;data = new int[bufferSize];} Table 9: Three examples that translate from Java to C# programming language on code translation task. [src] represents the source input, [ref] represents the reference, [sys] represents Transformer without data flow and [ours] represents GraphCodeBERT. Case1: Transformer adds redundant parameters (android.view.View view) [src] public void METHOD 1 ( ) { android.content.Intent V AR1 = new android.content.Intent ( V AR2 ) ; METHOD 2 ( V AR1 , 0 ) ; android.content.Intent i = new android.content.Intent ( this , V AR3 class ) ; METHOD 3 ( i ) ; } [ref] public void METHOD 1 ( ) { android.content.Intent V AR1 = new android.content.Intent ( V AR2 ) ; METHOD 2 ( V AR1 , 0 ) ; } [sys] public void METHOD 1 ( android.view.View view ){ android.content.Intent V AR1 = new android.content.Intent ( V AR2 ) ; METHOD 2 ( V AR1 , 0 ) ; } [ours] public void METHOD 1 ( ) { android.content.Intent V AR1 = new android.content.Intent ( V AR2 ) ; METHOD 2 ( V AR1 , 0 ) ; } Case2: Transformer outputs codes with severe logic or irrelevant codes [src] public java.util.Date METHOD 1 ( ) { return V AR1 . METHOD 1 ( ) . METHOD 2 ( ) ; } [ref] public java.util.Date METHOD 1 ( ) { if ( ( V AR1 . METHOD 1 ( ) ) != null ) { return V AR1 . METHOD 1 ( ) . METHOD 2 ( ) ; } else { return null ; } } [sys] public java.util.Date METHOD 1 ( ) { if ( ( V AR1 ) == null ) { return new java.util.Date ( ) ; } return V AR1 . METHOD 1 ( ) . METHOD 2 ( ) ; } [ours] public java.util.Date METHOD 1 ( ) { if ( ( V AR1 . METHOD 1 ( ) ) != null ) { return V AR1 . METHOD 1 ( ) . METHOD 2 ( ) ; } else { return null ; } } Case3: Transformer makes no change [src] public java.lang.String METHOD 1 ( TYPE 1 V AR1 ) { if ( V AR1 == null ) return null ; return V AR1 . METHOD 2 ( ) . getText ( ) ; } [ref] public java.lang.String METHOD 1 ( TYPE 1 V AR1 ) { return V AR1 . METHOD 2 ( ) . getText ( ) ; } [sys] public java.lang.String METHOD 1 ( TYPE 1 V AR1 ) { if ( V AR1 == null ) return null ; return V AR1 . METHOD 2 ( ) . getText ( ) ; } [ours] public java.lang.String METHOD 1 ( TYPE 1 V AR1 ) { return V AR1 . METHOD 2 ( ) . getText ( ) ; } Table 10: Three examples on code refinement task. [src] represents the source input, [ref] represents the reference, [sys] represents Transformer without data flow and [ours] represents GraphCodeBERT. 17 Published as a conference paper at ICLR 2021 G E RROR ANALYSIS We also conduct error analysis and summary two main classes of errors for both code understanding and generation tasks. Figure 11 gives three error cases of GraphCodeBERT on the natural language code search task. We observe that GraphCodeBERR mainly fails to retrieve those source code that involves functions of the library like “tf” (Tensorflow) in the first case and “ GoogleCloudStorageHook” in the second case. It’s difficult for GraphCodeBERR to understand meanings of APIs like “tf.io.read file” and “tf.image.decode image” without relevant information. A potential direction to mitigate the problem is to incorporate definitions of the library. The other major problem is that there are some termi- nologies like “unistr” in the query (corresponding to “decode(‘utf-8’)” in Python code) in third case. Incorporating more text-code pairs for pre-training might alleviate this problem. As for the code generation task, Table 11 shows two cases of GraphCodeBERT on the code translation task. We find that the major problems include semantic errors like identifiers from nowhere in the first case and syntax errors like missing a “ }” symbol before “return n” in the second case. This problem might be mitigated by incorporating a dedicated decoder that takes into account grammar of programming languages and different generation paradigm like generating a sequence of production rules (Yin & Neubig, 2017; Guo et al., 2018; 2019) in a context-free grammar manner. Case 1 Query: Return an image tensor. Gold Source Code: def read_image(filepath): im_bytes = tf.io.read_file(filepath) im = tf.image.decode_image(im_bytes, channels=CHANNELS) im = tf.image.convert_image_dtype(im, tf.float32) return im GraphCodeBERT: def get_image(self, float_key="floats", to_chw=True): tensors = callBigDlFunc(self.bigdl_type, "localImageFrameToImageTensor", self.value, float_key, to_chw) return map(lambda tensor: tensor.to_ndarray(), tensors) Case 2 Query: Uploads the file to Google cloud storage Gold Source Code: def execute(self, context): hook = GoogleCloudStorageHook( google_cloud_storage_conn_id=self.google_cloud_storage_conn_id, delegate_to=self.delegate_to) hook.upload( bucket_name=self.bucket, object_name=self.dst, mime_type=self.mime_type, filename=self.src, gzip=self.gzip, ) GraphCodeBERT: def upload(remote_path, local_path): storage = STORAGES['s3']() conf = s3conf.S3Conf(storage=storage) conf.upload(local_path, remote_path) Case 3 Query: json.loads wants an unistr in Python3. Convert it. Gold Source Code: def _json_safe(data): if not hasattr(data, 'encode'): try: data = data.decode('utf-8') except UnicodeDecodeError: raise ValueError( 'Expected valid UTF8 for JSON data, got %r' % (data,)) return data GraphCodeBERT: def parse_unstruct(unstruct): my_json = json.loads(unstruct) data = my_json['data'] schema = data['schema’] if 'data' in data: inner_data = data['data'] else: raise SnowplowEventTransformationException(["Could not extract inner data field from unstructured event"]) fixed_schema = fix_schema("unstruct_event", schema) return [(fixed_schema, inner_data)] Figure 11: Error cases of GraphCodeBERT on the natural language code search. Case1: semantic error – identifiers from nowhere. [src] public String toString() {return getKey() + “: ” + getValue();} [ref] public override string ToString(){return GetKey() + “: ” + GetValue();} [ours] public override string ToString(){return Name + “: ” + GetValue();} Case2: syntax errors – missing a “}” before “return n”) [src] public static int numNonnull(Object[] data) {int n = 0;if ( data == null ) return n; for (Object o : data) {if ( o!=null ) n++;}return n;} [ref] public static int NumNonnull(object[] data){int n = 0;if (data == null){return n;} foreach (object o in data){if (o != null){n++;}}return n;} [ours] public static int NumNonNull(object[] data){int n = 0;if (data == null){return n;} foreach (object o in data){if (o != null){n++;}return n;} Table 11: Error cases of GraphCodeBERT on the code translation task. [src] represents the source input, [ref] represents the reference and [ours] represents GraphCodeBERT. 18 Learning Compiler Pass Orders using Coreset and Normalized Value Prediction Youwei Liang∗1 Kevin Stone∗2 Ali Shameli2 Chris Cummins2 Mostafa Elhoushi2 Jiadong Guo2 Benoit Steiner2 Xiaomeng Yang2 Pengtao Xie1 Hugh Leather2 Yuandong Tian2 Abstract Finding the optimal pass sequence of compilation can lead to a significant reduction in program size and/or improvement in program efficiency. Prior works on compilation pass ordering have two ma- jor drawbacks. They either require an excessive budget (in terms of compilation steps) at compile time or fail to generalize to unseen programs. In this paper, for code-size reduction tasks, we pro- pose a novel pipeline to find program-dependent pass sequences within 45 compilation calls. It first identifies a coreset of 50 pass sequences via greedy optimization of a submodular func- tion, and then learns a policy with Graph Neural Network (GNN) to pick the optimal sequence by predicting the normalized values of the pass se- quences in the coreset. Despite its simplicity, our pipeline outperforms the default -Oz flag by an average of 4.7% over a large collection (4683) of unseen code repositories from diverse domains across 14 datasets. In comparison, previous ap- proaches like reinforcement learning on the raw pass sequence space may take days to train due to sparse reward, and may not generalize well in held-out ones from different domains. Our re- sults demonstrate that existing human-designed compiler flags can be improved with a simple yet effective technique that transforms the raw action space into a small one with denser rewards. 1. Introduction For more efficient execution with fewer resources (e.g., memory, CPU, and storage), applying the right ordering for compiler optimization passes to a given program, i.e., pass ordering, is an important yet challenging problem. Manual efforts require expert knowledge and are time-consuming, error-prone, and often yield sub-par results, due to the huge *Equal second author contribution, listed alphabetically. 1University of California, San Diego 2Meta AI. Correspondence to: Kevin Stone . Coreset Optimization Programs Reward Matrix Action sequences Optimize Coreset ... ... ... Normalized Value Prediction Inference Program Value Softmax ... Coreset GNN-GEAN Program Observation Figure 1.A depiction of our main contributions. (Top) Coreset Optimization: A process for discovering a small set of pass se- quences (coreset) that generalizes. (Bottom) Normalized Value Prediction A process where our model learns to predict the nor- malized value of pass sequences from the coreset. (Bottom inset) Our model, Graph Edge Attention Network (GEAN), for encoding program observations. size of the search space. For example, the LLVM compiler has 124 different compilation flags. If the pass sequences have a length of 45, then the possible number of sequences (12445 ∼1094) is already more than the atoms in the uni- verse (∼1080 (Planck Collaboration et al., 2016)). In recent years, machine learning (ML)-guided pass order- ing has emerged as an interesting field to replace this labori- ous process (Wang & O’Boyle, 2018). Along this line, many works show promising results using various optimization and/or ML techniques (e.g., reinforcement learning (Haj-Ali et al., 2020a), language modelling (Cummins et al., 2017), evolutionary algorithms (Kulkarni & Cavazos, 2012), etc). However, there are several limitations. Some previous works (e.g., MLGO (Trofin et al., 2021), MLGoPerf (Ashouri et al., 2022)) run adaptive search algorithms to optimize a set of programs for many hours. While this achieves strong per- formance gain, the procedure can be slow and does not distill knowledge from past experience and requires search- ing from scratch for unseen programs. Recent works like Autophase (Haj-Ali et al., 2020b) learn a pass policy via re- arXiv:2301.05104v2 [cs.PL] 27 Jan 2023 Learning Compiler Pass Orders using Coreset and Normalized Value Prediction inforcement learning, and applies it to unseen programs without further search procedure, and GO (Zhou et al., 2020) fine-tunes the models for unseen programs. These ap- proaches work for unseen programs from the same/similar domain, but can still be quite slow in the training stage, and do not show good generalization to programs from very different domains. In this work, we propose a novel pass ordering optimization pipeline to reduce the code size of a program. As a first contribution, we formulate the search for a universal core set of pass sequences (termed coreset) as an optimization problem of a submodular reward function and use a greedy algorithm to approximately solve it. The resulting coreset consists of 50 pass sequences with a total number of passes of 625. Importantly, it leads to very strong performance across programs from diverse domains, ranging from the Linux Kernel to BLAS. Specifically, for one unseen pro- gram in the evaluation set, there exists one of the 50 pass sequences that leads to an average code size reduction of 5.8% compared to the default -Oz setting, across 10 diverse codebases (e.g. Cbench (Fursin, 2014), MiBench (Guthaus et al., 2001), NPB (Bailey et al., 1995), CHStone (Hara et al., 2008), and Anghabench (Da Silva et al., 2021)) of over one million programs in total. Considering the huge search space of compiler flags, this is a very surprising finding. While it is time-consuming to find an optimal pass sequence with an exhaustive enumeration of the core subset of pass sequences, as a second contribution, we find that the (near) optimal pass sequence can be directly predicted with high accuracy via our Graph Edge Attention Network (GEAN), a graph neural network (GNN) architecture adapted to encode the augmented ProGraML (Cummins et al., 2021) graphs of programs. Therefore, we can run a few pass sequences selected by the model on an unseen program to obtain a good code size reduction. This enables us to find a good flag configuration that leads to 4.7% improvement on aver- age, with just 45 compilation passes, a reasonable trade-off between the cost spent on trying compilation passes and the resulting performance gain. We compare our approach with extensive baselines, includ- ing reinforcement learning (RL) -based methods such as PPO, Q-learning, and behavior cloning. We find that RL- based approaches operating on the original compiler pass space often suffer from unstable training (due to inaccurate value estimation) and sparse reward space and fail to gener- alize to unseen programs at inference. In comparison, our approach transforms the vast action space into a smaller one with much more densely distributed rewards. In this trans- formed space, approaches as simple as behavior cloning can be effective and generalizable to unseen programs. 2. Related Work Graph structured data are present in numerous applications and it has been shown that taking advantage of this data can help us train very effective machine learning models. (Brauckmann et al., 2020) use abstract syntax trees and con- trol flow graphs for learning compiler optimization goals. They show that using such graphs allows them to outper- form state-of-the-art in the task of heterogeneous OpenCL mapping. (Guo et al., 2020) uses a transformer based model with a graph guided masked attention that incorporates the data flow graph into the training. They achieve state of the art performance in four tasks including code search, clone detection, code translation, and code refinement. As a contender to graph neural networks, (Mialon et al., 2021) uses transformers to process graphs. They show that if we effectively encode positional and local sub-structures of graphs and feed them to the transformer, then the trans- former can outperform the classical GNN models. They test their model on classification and regression tasks and achieve state of the art performance. In (Srinivas et al., 2020), they used an unsupervised model to learn embed- dings of high dimensional pixel data using contrastive learn- ing. They then use this embedding for downstream rein- forcement learning tasks. 3. Methodology 3.1. Action space The CompilerGym framework (Cummins et al., 2022) pro- vides a convenient interface for the compiler pass ordering problem. The default environment allows choosing one of 124 discrete actions at each step corresponding to running a specific compiler pass. In this work we will use the term pass interchangeably with action. We fix episode lengths to 45 steps to match the setup in (Haj-Ali et al., 2020b). Given that our trajectories have a length of 45 steps, this means we have 12445 ∼1.6 ×1094 possible pass sequences to explore. To find an optimal pass sequence for a program, we can apply some existing reinforcement learning meth- ods including Q learning like DQN (Mnih et al., 2015) and policy gradient like PPO (Schulman et al., 2017). Pass SequencesHowever for this problem it turns out that certain pass sequences are good at optimizing many differ- ent programs (where “good” is defined as better than the compiler default -Oz). We found that constraining the ac- tion space to a learned set of pass sequences enables state of the art performance and also significantly reduces the challenge of exploration. This allows us to cast the problem as one of supervised learning over this set of pass sequences. We use the following algorithm to find a good set of pass sequences. Learning Compiler Pass Orders using Coreset and Normalized Value Prediction Figure 2.An exemplar reward matrix for 67 programs and 50 pass sequences. Most of the pass sequences do not lead to strong re- wards, except for a few. On the other hand, certain pass sequences (i.e., columns) can lead to high rewards for multiple programs simultaneously and thus are good candidates for the coreset. Suppose we have N programs and M promising pass se- quences. Let R= [rij] ∈RN×M be the reward matrix, in which rij >0 is the ratio of the codesize of i-th program if applied with j-th pass sequence, compared to -O0. rij >1 means that the j-th pass sequence does better than -O0 in codesize reduction for i-th program, and rij < 1 means it performs worse. The reward matrix is normalized per row, by the maximum reward for each program, so that the optimal pass sequence has reward of 1 for each program. Then we aim to pick a subset Sof Kpass sequences, called the coreset, from all M pass sequences, so that the overall saving J(S) is maximized: max |S|≤K J(S) = N∑ i=1 max j∈S rij (1) Finding M candidate pass sequences. Note that there can be exponential number of pass sequences, and we cannot construct the entire reward matrix, instead we seed a list of candidate action trajectories. For this, we run a random policy on a subset of M (17500) selected training programs. For each selected program, we run E (200) episodes and pick the best pass sequence as one of the M candidates. If part of the best pass sequence leads to the same state, they are truncated so that the sequence becomes shorter. If multiple pass sequences yield the same reward we only retain the first after ordering them length-lexicographically. On average these last two steps reduce the length of the candidate pass sequences by 80%. We then construct the rewardrij by applying the j-th best pass sequence to program i, and comparing it with -O0. Finding the best coresetS with greedy algorithm. As a function defined in subsets, J(S) can be proven to be a nonnegative and monotone submodular function (See Ap- pendix). While maximizing a submodular function is NP- hard (Ward & ˇZivn`y, 2016), the following greedy algorithm is proven to be an efficient approximate algorithm that leads to fairly good solutions (Nemhauser et al., 1978). Start- ing from S0 = ∅, at each iteration t, it picks a new pass sequence jt as follows: jt := arg max j/∈St−1 J(St−1 ∪{j}) (2) And St ←St−1 ∪{jt}until we pick Kpass sequences. We set K = 50 in this paper. Given the discovered coresetS, we define a generalized ac- tion as a pass sequence in S. Applying a generalized action to a program means that we roll out the corresponding pass sequence on the program and return the best program state (i.e., having the highest cumulative reward) (it is feasible because we can cache the program state for each step). 3.2. Normalized Value Prediction After discovering the “good” pass sequences (i.e., the core- set), we can turn the problem of the sequential decision- making on compiler passes into a problem of supervised learning. The target is to train a model to predict the best pass sequence conditioned on the program, where the label of the program is the index of the pass sequence that results in the largest code size reduction. However, one important observation we have is that there are typically multiple pass sequences in the coreset that all result in the largest code size reduction (see Figure 3 for the examples). Therefore, instead of using the single-class classification method with a cross entropy loss, we leverage the fact we have access to the values for all pass sequences. We predict the softmax normalized value of each pass sequence with a cross entropy loss detailed below. This approach is similar to behavior cloning (Pomerleau, 1988) but with soft targets over the coreset. For a program p, we roll out all pass sequences in the coreset on it, obtaining a reward rp j for the j-th sequence (i.e., the highest cumulative reward observed during the rollout of the pass sequence), which forms a value vector rp = [rp 1,...,r p K]. Then, the normalized values of the pass sequences are defined by vp = Softmax(rp/T) (3) where T is a temperature parameter. For an initial observation op of a program, our model out- puts a probability distribution, a = f(op), over the pass sequences. The target of the training is to make a close to the normalized values of the pass sequences. To this end, we use the Kullback–Leibler (KL) divergence to supervise the Learning Compiler Pass Orders using Coreset and Normalized Value Prediction model, which can be reduced to the following cross entropy loss up to a constant term. L(ap,vp) = − K∑ j=1 ap j log vp j (4) 3.3. Program Representations Since we use the CompilerGym (Cummins et al., 2022) environments for program optimization, we exploit the pro- gram representations from CompilerGym, where program source code is converted to LLVM Intermediate Represen- tation (IR) (Lattner & Adve, 2004) and several representa- tions are constructed from the IR, including the ProGraML graph (Cummins et al., 2021), the Autophase feature (Haj- Ali et al., 2020b), and the Inst2vec feature (Ben-Nun et al., 2018). We choose to use the LLVM environment from CompilerGym because the LLVM ecosystem is a popular compiler infrastructure that powers Swift, Rust, Clang, and more. Autophase We use the Autophase features Haj-Ali et al. (2020b) to build some baseline models for comparison, which will be detailed in Section 4.2. The Autophase feature is a 56-dimension integer feature vector summarizing the LLVM IR representation, and it contains integer counts of various program properties such as the number of instruc- tions and maximum loop depth. we use an MLP to encode it and output a program representation. ProGraML As a part of our main method, we leverage ProGraML (Cummins et al., 2021) graphs for training GNN models. ProGraML is a graph-based representation that en- codes semantic information of the program which includes control flow, data flow, and function call flow. This repre- sentation has the advantage that it is not a fixed size - it does oversimplify large programs - and yet it is still a more compact format than the original IR format. We list three bullet points of the ProGraML graph below. • Node featuresEach node in a ProGraML graph have 4 features described in Table 1. The “text” feature is a textual representation and the main feature that captures the semantics of a node. For example, it tells us what an “instruction” node does (e.g., it can be alloca, store, add, etc). • Edges featuresEach edge in a ProGraML graph have 2 features described in Table 1. • Type graph There is an issue with the ProGraML graph. Specifically, a node of type variable/constant node can end up with a long textual representation (for the “text” feature) if it is a composite data struc- ture. For example, a struct (as in C/C++) contain- ing dozens of data members needs to include all the members in its “text” feature. In other words, the current ProGraML representation does not automati- cally break down composite data types into their ba- sic components. Since there is an unbounded num- ber of possible structs, this prevents 100% vocabulary coverage on any IR with structs (or other composite types). To address this issue, we propose to expand the node representing a composite data type into a type graph. Specifically, a pointer node is expanded into this type graph: [variable] <- [pointer] <- [pointed-type], where [...]denotes a node and <-denotes an edge connection. A struct node is ex- panded into a type graph where all its members are represented by individual nodes (which may be fur- ther expanded into their components) and connected to a structnode. An array is expanded into this type graph:[variable] <- [array] <- [element- type]. The newly added nodes are categorized as type nodes and the edges connecting the type nodes are type edges. The type nodes and type edges con- stitute the type sub-graphs in the ProGraML graphs. In this manner, we break down the composite data struc- tures into the type graphs that consist of only primitive data types such as float and i32. 3.4. Network Architecture Since the Autophase feature can be encoded by a simple MLP, we discuss only the network architectures for encod- ing the ProGraML graphs in this section. We use a graph neural network (GNN) as the backbone to encode the ProGraML graphs and output a graph-level representation. The GNN encodes the graph via multiple layers of message passing and outputs a graph-level repre- sentation by a global average pooling over the node features. The goal of graph encoding is to use the structure and re- lational dependencies of the graph to learn an embedding that allows us to learn a better policy. To this end, we ex- perimented with several different GNN architectures such as Graph Convolutional Network (GCN) (Kipf & Welling, 2017), Gated Graph Convolutions Network (GGC) (Li et al., 2015), Graph Attention Network (GAT) (Brody et al., 2022), Graph Isomorphism Network (GIN) (Xu et al., 2019). To better capture the rich semantics of node/edge features in the ProGraML graphs, we propose Graph Edge Attention Network ( GEAN), a variant of the graph attention net- work (Veliˇckovi´c et al., 2017). These GNNs leverage both the node and edge features, so we start by presenting how to embed the node and edge features. Node embeddingFor the “text” features of the nodes, we build a vocabulary that maps from text to integer. The vocabulary covers all the text fields of the nodes in the graphs in the training set. The final vocabulary consists of Learning Compiler Pass Orders using Coreset and Normalized Value Prediction Feature Description Node type One of {instruction, variable, constant,type} text Semantics of the node function Integer position in function block Integer position in IR basic block Edge flow Edge type. One of {call, control, data,type} position Integer edge position in flow branching Table 1.Features in the ProGraML graph representation which we augment with type information (changes highlighted). We ablate the augmentations in Section 4.5. 117 unique textual representations, and we add an additional item “unknown” to the vocabulary which denotes any text features that may be encountered at inference time and we have not seen before. The i-th textual representation is embedded using a learnable vector vi ∈Rd, where d is the embedding dimension. The “type” feature is not used because it can be inferred from the “text” feature. Edge embeddingThe edge embedding is the sum of three types of embedding as the following. • Type embeddingWe have 4 types of edge flows, so we use 4 learnable vectors to represent them. • Position embeddingThe “position” feature of an edge is a non-negative integer which does not have an upper bound. We truncate any edge positions larger than 32 to 32 and use a set of 32 learnable vectors to represent the edge positions. • Block embedding We use the block indices of the two nodes connected by the edge to construct a new edge feature. The motivation is that whether the edge goes beyond an IR basic block can influence program optimization. Suppose the block indices of the source node and the target node of an edge are respectively bi and bj. We get the relative position of the two nodes with respect to IR basic blocks in the following way: pblock = sign(bi−bj). If the edge connects two nodes in the same IR basic block, then pblock is 0. And pblock = ±1 indicates the edge goes from a block to the next/previous block. There are 3 possible values for pblock, so it is embedded using 3 learnable vectors. The final embedding of an edge is the sum of its type, posi- tion, and block embedding vectors. Graph mixupWe note that the ProGraML graphs of two programs can be composed into a single graph without af- fecting the semantics of the two programs. And their value vectors can be added up to correctly represent the value vec- tor of the composite graph. In this manner, we can enrich the input space to the GNNs and mitigate model overfitting for the normalized value prediction method. Graph Edge Attention NetworkWe introduce the GEAN in this paragraph and defer its mathematical details to the Appendix. There are two main differences between the GAT and GEAN. 1) GEAN adopts a dynamic edge representa- tion. Specifically, GAT uses the node-edge-node feature to calculate the attention for neighborhood aggregation, while GEAN uses the node-edge-node feature to calculate not only the attention but also a new edge representation. Then, the updated edge representation is sent to the next layer for computation. Note that GAT uses the same edge embedding in each layer. We conduct an ablation study showing that the edge representation in GEAN improves the generaliza- tion of the model. 2) GAT treats the graph as an undirected graph while GEAN encodes the node-edge-node feature to output an updated node-edge-node feature, where the two updated node features represent the feature to be aggregated in the source node and the target node, respectively. This ensures that the directional information is preserved in the neighborhood aggregation. 3.5. Dataset Preparation Overfitting issues could happen if training is performed on a small subset of programs, or the set of programs is not diverse enough. To mitigate this we find it helpful to create an aggregate dataset that uses many different public datasets as curated by CompilerGym. CompilerGym gives us access to 14 different datasets constructed using two different methods. • Curated These are small collections of hand-picked programs. They are curated to be distinct from one another without overlap and are not useful for training. Typically programs are larger as they may comprise multiple source files combined into a single program. These are commonly used for evaluating compiler op- timization improvements. • Uncurated These are comprised of individual com- piler IRs from building open source repositories such as Linux and Tensorflow. We also include synthetically generated programs, targeted for compiler testing (not optimization). For our aggregate dataset we decided to holdout the entirety of the four curated datasets for use as an out-of-domain test set. This is important because they represent the types of programs we expect to see in the wild. We also split the uncurated datasets into train, validaton, and test programs. 3.6. Evaluation For all our metrics and rewards we leverage the IR instruc- tion count as value we are trying to minimize. We also report metrics on each CompilerGym dataset as well as Learning Compiler Pass Orders using Coreset and Normalized Value Prediction Type Dataset Train Val Test Uncurated anghabench-v1 70,7000 1,000 2,000 blas-v0 133 28 29 github-v0 7,000 1,000 1,000 linux-v0 4,906 1,000 1,000 opencv-v0 149 32 32 poj104-v1 7,000 1,000 1,000 tensorflow-v0 415 89 90 clgen-v0 697 149 150 csmith-v0 222 48 48 llvm-stress-v0 697 149 150 Curated cbench-v1 0 0 11 chstone-v0 0 0 12 mibench-v1 0 0 40 npb-v0 0 0 121 Total - 728,219 4,495 4,683 Table 2.CompilerGym dataset types and training splits. The hand curated datasets are used solely to evaluate generalization to real world program domains at test time. the mean over datasets to get a single number to compare overall results. • The mean percent improved over-Oz (MeanOverOz) defined as following: ¯IOz = MeanOverOz := 1 |P| ∑ p IOz p −Iπθ p IOzp , (5) where pis a specific program from the set of programs Pin the dataset. IOz p is the number of IR instructions in the program after running the default compiler pass -Oz. Iπθ p is the number of IR instructions in the pro- gram after applying the policy under consideration. We can think of this as a simple average of the percent improvement over -Oz. • We also look compare the geometric mean (GMeanOverOz) of final sizes across all pro- grams relative to -Oz to give a weighted comparison that is insensitive to outliers. ¯IOz G = GMeanOverOz := (∏ p IOz p Iπθ p ) 1 |P| (6) 4. Experiments 4.1. Experimental Setup For the methods in Table 3, we search over a set of hyper- parameters, including the temperature T in Eq. 3, number of layers, the embedding dimension of the node/edge fea- tures, and the output dimension in the hidden layers in the MLPs. We select the best model of each method based on the validation metric (validation MeanOverOz in 45 steps) and report the best model’s metrics on the test set. 4.2. Baseline Methods Oracle We consider a brute-force search over the coreset in order to find the best pass sequence for a given program. This gives us an upper-bound of the downstream policy network. In our case the coreset has a total of 50 sequences (625 total passes). Top-45We also consider how well we would do if the oracle is only allowed to use the most popular pass sequences but limited to 45 passes. We use 45 passes because this is maximum allowed for our all other baselines and our proposed method. RL-PPO We reproduce the Autophase (Haj-Ali et al., 2020b) pipeline by using the state-of-the-art RL algorithm PPO (Schulman et al., 2017) to learn a policy model. We have two program representations for training the RL mod- els, including the Autophase feature and the ProGraML graphs (note that Haj-Ali et al. (2020b) only used the Autophase feature). The Autophase/ProGraML feature is sent to a GNN/MLP for feature encoding, which out- puts a program-level embedding. Following Haj-Ali et al. (2020b), we add an additional action history feature to the RL pipeline, which is a histogram of previously applied passes. The vector of the histogram of action history is divided by 45 (i.e., the number of the total passes in our budget) for normalization. A 2-layer MLP is used to encode the action history to obtain a feature vector, which is con- catenated with the program embedding extracted from the ProGraML graph or the Autophase feature. The concate- nated feature is sent to a 2-layer MLP to output the action probability for the policy network. The value network (i.e., the critic) in our PPO pipeline mimics the policy network (i.e., the actor) in feature encoding and outputs a scalar to es- timate the state values. The state values are the expectation of the discounted cumulative rewards where the reward in each step is the improvement over -O0: (I(t) p −Iπθ p )/I(t) p , where I(t) p denotes the current IR instruction count of the program pat time step t. This reward is reasonable since it makes the value approximation Markovian. At inference, an action is sampled from the output of the learned policy network at each time step until the total number of steps reaches 45. Q-value-rank We consider each pass sequence in the core- set as a generalized action and train a Q network to predict the value of each generalized action. Recall that the value vector rp is the highest cumulative reward observed during the rollout of each pass sequence in the coreset on program p. The Q-value-rank model is trained to approximate the value vector using a mean squared loss. Learning Compiler Pass Orders using Coreset and Normalized Value Prediction Figure 3.GEAN-Q-value-rank: ground truth of rewards and model predictions over the 50 generalized actions for three benchmarks. BC We consider learning a standard behavior cloning model to predict the best pass sequences from the coreset, where the best pass sequence is defined as the following. As in the previous bullet point, the value vector is denoted byrp. If there is only one isuch that rp i = maxj∈nrp j, then the clas- sification label is i. If there are multiple such i’s (multiple pass sequences) that achieve the largest reward maxj∈nrp j, then we order the corresponding pass sequences by length- lexicographic ordering. The classification label is selected to be the first one after the ordering. This ensures that our definition for the best pass sequence (among the coreset) for a program is unique and consistent. We use a standard cross entropy loss to train the single-class classification model. NVP This is the normalized value prediction method de- scribed in Section 3.2. The last three methods (i.e., Q-value-rank, BC, and NVP) share the same inference protocol. Note that they all output a vector a of length 50 whose entries correspond to the pass sequences in the coreset. At inference, we roll out the pass sequences with the highest values in a one by one until our budget of 45 passes is reached. Since the pass sequence has an average length of 12.5, typically 3 or 4 pass sequences are applied (anything beyond 45 passes will be truncated). For BC and NVP, we also tried sampling pass sequences using the model output a, but that resulted in worse performance. Therefore, we stick to selection by maximum values. 4.3. Main Results In Table 3 we present the main results of our experiments comparing our proposed method -NVP to various base- lines. The test programs were completely held-out during both data-driven learning phases (pass sequence search and model training). The results show that our model achieves strong perfor- mance over the prior method (Autophase-RL-PPO) pro- posed in (Haj-Ali et al., 2020b). Additionally, we can see that both the GEAN model and the normalized value pre- diction over the discovered coreset are needed to achieve the best performance within 45 passes. See Figure 6 in the Method #passes ¯IOz ¯IOz G Compiler (-Oz) - 0% 1.000 Autophase-RL-PPO 45 -16.3% 0.960 GCN-RL-PPO 45 -12.2% 0.987 GGC-RL-PPO 45 -8.5% 1.000 GIN-RL-PPO 45 -11.3% 0.991 GAT-RL-PPO 45 -10.3% 0.999 GEAN-RL-PPO 45 -10.0% 0.997 GEAN-Q-value-rank 45 -0.3% 1.043 Autophase-BC 45 2.6% 1.043 GEAN-BC 45 2.1% 1.038 Autophase-NVP (Ours) 45 3.8% 1.054 GCN-NVP (Ours) 45 4.4% 1.058 GGC-NVP (Ours) 45 4.1% 1.056 GIN-NVP (Ours) 45 4.2% 1.056 GAT-NVP (Ours) 45 4.1% 1.055 GEAN-NVP (Ours) 45 4.7% 1.062 Top-45 45 -7.5% 0.992 Oracle 625 5.8% 1.075 Table 3.Evaluation results on held-out test setaveraged over all datasets. ¯IOz denotes per-program MeanOverOz, and ¯IOz G de- notes GMeanOverOz over all programs. All methods except Compiler and Oracle baselines use 45 compiler optimization passes. Appendix for a visualization of the improvement in program size over the 45 passes on programs from the holdout set. The Oracle shows strong performance but requires a large number of interactions with the compiler. But, this shows that the pass sequence search generalizes to new unseen programs. This is somewhat unsurprising given that the compiler’s built-in hand-tuned pass list (-Oz) works reason- ably well for most programs. The performance of Top-45 by itself is weak showing that in order to achieve good results in a reasonable number of passes (45) we need to leverage a general policy and Learning Compiler Pass Orders using Coreset and Normalized Value Prediction search to select the most likely candidate pass sequences to evaluate. 4.4. Why Did the RL-PPO Baseline Fail? We provide an empirical analysis of why the RL-PPO ap- proaches obtain much lower performance compared to our NVP approaches. We hypothesize two possible reasons for the failures of RL-PPO. 1) Inaccurate state-value estima- tion results in a high variance in training.In the PPO algorithm, we have a policy network (the actor) to output a probability distribution over the actions. And we have a value network (the critic) for estimating the state val- ues, where the approximation is based on regressing the cumulative reward of trajectories sampled from the current policy (Schulman et al., 2017). The update of the policy network is based on the state value outputted by the value network. Inaccurate state value estimation results in a high variance in training the policy network. Due to the stochas- tic nature of the value estimation that stems from the Monte Carlo sampling in cumulative reward regression, it is diffi- cult to analyze how accurately the value network approx- imates the ground truth state values (which are unknown even for the programs in the training set). We alleviate this issue by analyzing the Q-value-rank approach (as introduced in Section 4.2), which can be seen as a sim- plified version of the value approximation in PPO. The Q-value-rank approach is simpler because the values to estimate are deterministic (i.e., the value vector rp is fixed for a program p). Moreover, since we consider the 50 pass sequences in our coreset as 50 generalized actions, the Q-value-rank approach can be seen as the value approximation in a PPO pipeline where a trajectory consists of only a single step over the 50 generalized actions. In this sense, the Q-value-rank approach is a simplified version of the regular value estimation in PPO. Figure 3 shows that the value estimation is inaccurate for programs in the held-out test set even for Q-value-rank approach. Therefore, it is even more challenging to estimate the state values in PPO. The inaccuracy leads to a high variance in training the policy network. 2) The reward is very sparse. As shown in Figure 2, the rewards are very sparse. There- fore, the good states (i.e., the program states with a higher chance to be optimized in code size reduction) are rarely seen by the value/policy network during rollouts. Then, the value network does not have a good value estimation for those good states, and the policy network does not converge to output a good policy for them. We conjecture these two issues are the main reason for why the RL-PPO methods obtain the worst performance as shown in Table 3. 4.5. Ablation Studies Ablation for GEAN-NVPWe perform 3 ablation exper- iments for GEAN-NVP, where we remove graph mixup, Figure 4.The effect of temperature on GEAN-NVP. Method Test MeanOverOz GEAN-NVP 4.7% (0.0%) - graph mixup 4.4% (-0.3%) - edge embedding 4.4% (-0.3%) - type graph -5.3% (-10.0 %) Table 4.Ablation on GEAN-NVP components. mask the edge embedding, and remove the type graph, respectively. The results in Table 4 show that the test MeanOverOz metric drops after removing any of the three components. Specifically, the performance drops signifi- cantly after removing the type graph, which validates its importance. The effect of the temperatureThe temperature parameter T in Eq. 3 controls how sharp the target distribution is. The distribution tends to be sharper as the temperature decreases. To analyze the influence of the temperature on the general- ization of the model, We vary the temperature T in training the GEAN-NVP model and report the results in Figure 4. 5. Conclusions In this paper, we develop a pipeline for program size re- duction under limited compilation passes. We find that it is a great challenge to approximate the state values (i.e., the maximum code size reduction) for a diverse set of programs, so existing state-of-the-art methods such as proximal policy optimization (PPO) fail to obtain good performances. To tackle this problem, we propose a search algorithm that dis- covers a good set of pass sequences (i.e., the coreset), which generalizes well to unseen programs. Moreover, we propose to train a GNN to approximate the normalized state values of programs over the coreset, for which we propose a variant of the graph attention network, termed GEAN. Our pipeline of coreset discovery and normalized value prediction via GEAN perform significantly better than the PPO baselines. Learning Compiler Pass Orders using Coreset and Normalized Value Prediction References Ashouri, A. H., Elhoushi, M., Hua, Y ., Wang, X., Manzoor, M. A., Chan, B., and Gao, Y . Mlgoperf: An ml guided inliner to optimize performance, 2022. URL https: //arxiv.org/abs/2207.08389. Bailey, D., Harris, T., Saphir, W., Van Der Wijngaart, R., Woo, A., and Yarrow, M. The nas parallel benchmarks 2.0. Technical report, Technical Report NAS-95-020, NASA Ames Research Center, 1995. Ben-Nun, T., Jakobovits, A. S., and Hoefler, T. Neural code comprehension: A learnable representation of code semantics. Advances in Neural Information Processing Systems, 31, 2018. Brauckmann, A., Goens, A., Ertel, S., and Castrillon, J. Compiler-based graph representations for deep learning models of code. In CC, pp. 201–211, 2020. Brody, S., Alon, U., and Yahav, E. How attentive are graph attention networks? In International Confer- ence on Learning Representations, 2022. URL https: //openreview.net/forum?id=F72ximsx7C1. Cummins, C., Petoumenos, P., Wang, Z., and Leather, H. End-to-end deep learning of optimization heuristics. In 26th International Conference on Parallel Architectures and Compilation Techniques (PACT). IEEE, 2017. Cummins, C., Fisches, Z. V ., Ben-Nun, T., Hoefler, T., O’Boyle, M. F. P., and Leather, H. ProGraML: A Graph- based Program Representation for Data Flow Analysis and Compiler Optimizations. In ICML, 2021. Cummins, C., Wasti, B., Guo, J., Cui, B., Ansel, J., Gomez, S., Jain, S., Liu, J., Teytaud, O., Steiner, B., et al. Com- pilergym: robust, performant compiler optimization en- vironments for ai research. In 2022 IEEE/ACM Interna- tional Symposium on Code Generation and Optimization (CGO), pp. 92–105. IEEE, 2022. Da Silva, A. F., Kind, B. C., de Souza Magalh ˜aes, J. W., Rocha, J. N., Guimaraes, B. C. F., and Pereira, F. M. Q. Anghabench: A suite with one million compilable c benchmarks for code-size reduction. In 2021 IEEE/ACM International Symposium on Code Generation and Opti- mization (CGO), pp. 378–390. IEEE, 2021. Fursin, G. Collective tuning initiative. arXiv preprint arXiv:1407.3487, 2014. Guo, D., Ren, S., Lu, S., Feng, Z., Tang, D., Liu, S., Zhou, L., Duan, N., Svyatkovskiy, A., Fu, S., et al. Graphcode- bert: Pre-training code representations with data flow. arXiv preprint arXiv:2009.08366, 2020. Guthaus, M. R., Ringenberg, J. S., Ernst, D., Austin, T. M., Mudge, T., and Brown, R. B. Mibench: A free, commer- cially representative embedded benchmark suite. In Pro- ceedings of the fourth annual IEEE international work- shop on workload characterization. WWC-4 (Cat. No. 01EX538), pp. 3–14. IEEE, 2001. Haj-Ali, A., Ahmed, N. K., Willke, T., Shao, Y . S., Asanovic, K., and Stoica, I. Neurovectorizer: End-to-end vectoriza- tion with deep reinforcement learning. In Proceedings of the 18th ACM/IEEE International Symposium on Code Generation and Optimization, pp. 242–255, 2020a. Haj-Ali, A., Huang, Q. J., Xiang, J., Moses, W., Asanovic, K., Wawrzynek, J., and Stoica, I. Autophase: Jug- gling hls phase orderings in random forests with deep reinforcement learning. In Dhillon, I., Pa- pailiopoulos, D., and Sze, V . (eds.), Proceedings of Machine Learning and Systems , volume 2, pp. 70–81, 2020b. URL https://proceedings. mlsys.org/paper/2020/file/ 4e732ced3463d06de0ca9a15b6153677-Paper. pdf. Hara, Y ., Tomiyama, H., Honda, S., Takada, H., and Ishii, K. Chstone: A benchmark program suite for practical c-based high-level synthesis. In 2008 IEEE International Symposium on Circuits and Systems (ISCAS), pp. 1192– 1195. IEEE, 2008. Kipf, T. N. and Welling, M. Semi-supervised classi- fication with graph convolutional networks. In In- ternational Conference on Learning Representations , 2017. URL https://openreview.net/forum? id=SJU4ayYgl. Kulkarni, S. and Cavazos, J. Mitigating the compiler opti- mization phase-ordering problem using machine learning. In Proceedings of the ACM international conference on Object oriented programming systems languages and ap- plications, pp. 147–162, 2012. Lattner, C. and Adve, V . Llvm: A compilation framework for lifelong program analysis & transformation. In Inter- national Symposium on Code Generation and Optimiza- tion, 2004. CGO 2004., pp. 75–86. IEEE, 2004. Li, Y ., Tarlow, D., Brockschmidt, M., and Zemel, R. Gated graph sequence neural networks. arXiv preprint arXiv:1511.05493, 2015. Mialon, G., Chen, D., Selosse, M., and Mairal, J. Graphit: Encoding graph structure in transformers, 2021. Mnih, V ., Kavukcuoglu, K., Silver, D., Rusu, A. A., Veness, J., Bellemare, M. G., Graves, A., Riedmiller, M., Fidje- land, A. K., Ostrovski, G., et al. Human-level control Learning Compiler Pass Orders using Coreset and Normalized Value Prediction through deep reinforcement learning. nature, 518(7540): 529–533, 2015. Nemhauser, G. L., Wolsey, L. A., and Fisher, M. L. An analysis of approximations for maximizing submodular set functions—i. Mathematical programming, 14(1):265– 294, 1978. Planck Collaboration et al. Planck 2015 results - xiii. cosmological parameters. Astronomy & Astrophysics , 594:A13, 2016. doi: 10.1051/0004-6361/201525830. URL https://doi.org/10.1051/0004-6361/ 201525830. Pomerleau, D. A. Alvinn: An autonomous land vehicle in a neural network. In Touretzky, D. (ed.), Advances in Neu- ral Information Processing Systems, volume 1. Morgan- Kaufmann, 1988. URL https://proceedings. neurips.cc/paper/1988/file/ 812b4ba287f5ee0bc9d43bbf5bbe87fb-Paper. pdf. Schulman, J., Wolski, F., Dhariwal, P., Radford, A., and Klimov, O. Proximal policy optimization algorithms. arXiv preprint arXiv:1707.06347, 2017. Srinivas, A., Laskin, M., and Abbeel, P. Curl: Contrastive unsupervised representations for reinforcement learning, 2020. Trofin, M., Qian, Y ., Brevdo, E., Lin, Z., Choromanski, K., and Li, D. Mlgo: a machine learning guided com- piler optimizations framework, 2021. URL https: //arxiv.org/abs/2101.04808. Veliˇckovi´c, P., Cucurull, G., Casanova, A., Romero, A., Lio, P., and Bengio, Y . Graph attention networks.arXiv preprint arXiv:1710.10903, 2017. Wang, Z. and O’Boyle, M. Machine learning in compiler optimization. Proceedings of the IEEE, 106(11):1879– 1901, 2018. Ward, J. and ˇZivn`y, S. Maximizing k-submodular functions and beyond. ACM Transactions on Algorithms (TALG), 12(4):1–26, 2016. Xu, K., Hu, W., Leskovec, J., and Jegelka, S. How powerful are graph neural networks? In International Conference on Learning Representations, 2019. URL https:// openreview.net/forum?id=ryGs6iA5Km. Zhou, Y ., Roy, S., Abdolrashidi, A., Wong, D., Ma, P., Xu, Q., Liu, H., Phothilimtha, P., Wang, S., Goldie, A., et al. Transferable graph optimizers for ml compilers. Advances in Neural Information Processing Systems, 33: 13844–13855, 2020. Learning Compiler Pass Orders using Coreset and Normalized Value Prediction A. Proofs Lemma A.1. The objective J(S) defined in Eqn. 1 max |S|≤K J(S) = N∑ i=1 max j∈S rij (7) (with the additional definition J(∅) = 0), is a nonnegative and monotone submodular function. Proof. Since rij >0, it is clear that J(S) ≥0 is nonnegative. To incorporate the special case J(∅) = 0, note that J(S) can be written as max |S|≤K J(S) = N∑ i=1 max ( max j∈S rij,0 ) . (8) Let ˆrij = rij and ˆri,0 = 0, then in order to prove J(S) is monotone and submodular, by additivity, we only need to prove Ji(S) := maxj∈S∪{0}ˆrij is monotone and submodular. For any A⊆B, it is clear that Ji(A) = max j∈A∪{0} ˆrij ≤ max j∈B∪{0} ˆrij = Ji(B) (9) So Ji(S) is monotone. To prove submodularity, for any A ⊆B, we comare the quatity of Ji(A∪{j}) −Ji(A) and Ji(B∪{j}) −Ji(B) for j /∈B. Case 1: ˆrij is a maximum over the subsetB. In this case, then ˆrij is also a maximum over the subset A. Then Ji(A∪{j}) = Ji(B∪{j}) = ˆrij, since Ji(A) ≤Ji(B), we have: Ji(A∪{j}) −Ji(A) ≥Ji(B∪{j}) −Ji(B) (10) Case 2: ˆrij is a maximum overAbut not inB. Then Ji(A∪{j}) −Ji(A) ≥0, but Ji(B∪{j}) −Ji(B) = 0 . So Eqn. 10 still holds. Case 3:ˆrij is neither a maximum inAor inB. Then both Ji(A∪{j}) −Ji(A) = 0 and Ji(B∪{j}) −Ji(B) = 0. So Eqn. 10 still holds. By definition of submodularity (Eqn. 10), we know Ji(S) is submodular and so does J(S). B. GEAN Encoding Our Graph Edge Attention Network (GEAN) has the following key features. Attention with edge featuresWe modify the attention mechanism in GAT to output an edge embedding and two node features for neighborhood aggregation. For clarity, we show a table containing the notations used in the GNN in Table 5. The feature update process can be mathematically defined by the following equations, where Mi,i = 1,..., 5 is an encoding fully connected layer. X′(t+1) ij = M1(X(t) i ,E(t) i→j,X(t) j ), (11) a′(t+1) ij = M2(X(t) i ,E(t) i→j,X(t) j ), (12) X(t+1) ji = M3(X(t) i ,E(t) i→j,X(t) j ), (13) a(t+1) ji = M4(X(t) i ,E(t) i→j,X(t) j ), (14) E(t+1) i→j = M5(X(t) i ,E(t) i→j,X(t) j ), (15) Learning Compiler Pass Orders using Coreset and Normalized Value Prediction 1 2 5 3 𝑋!"#𝑋!$# 𝑋!%# 𝑋"&#𝑋"! 𝑋%! 𝑋$! 𝑋&" 4 Figure 5.Graph attention. Circles denote nodes and solid arrows denote edges. Squares are the calculated features, and dash arrows represent feature aggregation. The orange/green squares denote the features to be aggregated in the target/source nodes of the edges. The edge embedding and the attention are not shown. Notation Meaning E The set of edges in the graph (i,j) Edge from node ipointing to node j X(t) i Representation of node iat layer t E(t) i→j Representation of the edge (i,j) at layer t X(t) ij Representation for node iassociated with edge (i,j) X′(t) ij Representation for node iassociated with edge (j,i) a(t) ij Raw attention associated with representation X(t) ij a′(t) ij Raw attention associated with representation X′(t) ij α(t) ij Normalized attention associated with a(t) ij α′(t) ij Normalized attention associated with a′(t) ij Ti Target neighbors of node i: {j|(i,j) ∈E} Si Source neighbors of node i: {j|(j,i) ∈E} Table 5.The notations in GEAN. In words, the node-edge-node triplet, (X(t) i ,E(t) i→j,X(t) j ), associated with edge (i,j), is encoded by fully connected layers to output 5 features, including X′(t+1) ij and a′(t+1) ij (a representation and attention to be aggregated in node i), and X(t+1) ji and a(t+1) ji (a representation and attention to be aggregated in node j), and the updated edge representation E(t+1) i→j . Note that the features to be aggregated to a target node are marked with the ′, and those to a source node are without the ′(see Figure 5). After the feature encoding, we perform an attention-weighted neighborhood aggregation for each node, which can be mathematically described by the following equations. [[ α(t+1) ij ] j∈Ti  [ α′(t+1) ij ] j∈Si ] = Softmax [[ a(t+1) ij ] j∈Ti  [ a′(t+1) ij ] j∈Si ] (16) X(t+1) i = ∑ j∈Ti α(t+1) ij X(t+1) ij + ∑ j∈Si α′(t+1) ij X′(t+1) ij (17) where ∥denotes concatenation. Learning Compiler Pass Orders using Coreset and Normalized Value Prediction In comparison, GAT only outputs an attention score by encoding the node-edge-node triplet: a(t+1) ij = (X(t) i ,E(t) i→j,X(t) j ), and the feature for neighborhood aggregation is only conditioned on the neighbors: X(t+1) ij = MLP(X(t) j ). To summarize, our encoding approach can ensure that the GNN model is aware of the direction of the edge and that the edge embedding is updated in each layer, which helps improve the performance (as shown in Table 3). C. Detailed Results Dataset Oracle Top-45 Autophase-RL-PPO Autophase-NVP GEAN-RL-PPO GEAN-NVP anghabench-v1 0.7%/1.011 -1.0%/0.996 -15.9%/0.974 -0.2%/1.002 -0.8%/0.996 -0.0%/1.003 blas-v0 2.6%/1.028 -0.4%/0.997 -1.7%/0.984 2.1%/1.023 -1.0%/0.990 2.4%/1.026 cbench-v1 3.5%/1.041 -2.4%/0.984 -10.1%/0.925 -0.1%/1.008 -1.6%/0.998 2.2%/1.028 chstone-v0 9.3%/1.106 1.2%/1.016 1.3%/1.018 8.3%/1.095 5.4%/1.060 8.8%/1.101 clgen-v0 5.4%/1.060 3.1%/1.034 -0.5%/0.998 4.6%/1.051 0.3%/1.005 5.0%/1.056 csmith-v0 21.2%/1.320 -96.3%/0.851 -116.0%/0.954 21.1%/1.320 -124.6%/0.965 21.1%/1.320 github-v0 1.0%/1.011 0.2%/1.002 0.1%/1.001 0.9%/1.010 -0.2%/0.999 0.9%/1.010 linux-v0 0.6%/1.007 -0.4%/0.998 -0.5%/0.997 0.6%/1.006 -2.3%/0.989 0.6%/1.007 llvm-stress-v0 6.3%/1.087 -18.9%/0.885 -67.0%/0.731 0.7%/1.035 -17.5%/0.888 2.1%/1.045 mibench-v1 1.7%/1.020 0.0%/1.003 -2.8%/0.976 -5.8%/0.963 -0.3%/1.000 -0.1%/1.003 npb-v0 9.8%/1.159 5.7%/1.085 0.9%/1.035 5.1%/1.079 3.7%/1.068 5.5%/1.085 opencv-v0 5.2%/1.061 1.0%/1.013 0.5%/1.007 4.2%/1.051 0.3%/1.004 4.8%/1.057 poj104-v1 7.8%/1.105 3.9%/1.055 -17.5%/0.876 6.1%/1.080 -0.7%/1.008 6.3%/1.082 tensorflow-v0 6.1%/1.077 -0.2%/0.998 0.2%/1.004 5.9%/1.075 -0.2%/0.998 5.9%/1.075 Average 5.8%/1.075 -7.5%/0.992 -16.3%/0.960 3.8%/1.054 -10.0%/0.997 4.7%/1.062 Table 6.Detailed evaluation results on held-out test sets. Learning Compiler Pass Orders using Coreset and Normalized Value Prediction D. Trajectory comparison Figure 6.Program optimization example over many steps comparing the Autophase-RL-PPO (blue) approach with our GEAN-NVP (orange) approach. The dashed line represents the compiler default -Oz performance and higher is better. Learning Compiler Pass Orders using Coreset and Normalized Value Prediction E. Compiler passes Index Flag Index Flag Index Flag 0 -add-discriminators 42 -globalsplit 84 -lower-expect 1 -adce 43 -guard-widening 85 -lower-guard-intrinsic 2 -aggressive-instcombine 44 -hotcoldsplit 86 -lowerinvoke 3 -alignment-from-assumptions 45 -ipconstprop 87 -lower-matrix-intrinsics 4 -always-inline 46 -ipsccp 88 -lowerswitch 5 -argpromotion 47 -indvars 89 -lower-widenable-condition 6 -attributor 48 -irce 90 -memcpyopt 7 -barrier 49 -infer-address-spaces 91 -mergefunc 8 -bdce 50 -inferattrs 92 -mergeicmps 9 -break-crit-edges 51 -inject-tli-mappings 93 -mldst-motion 10 -simplifycfg 52 -instsimplify 94 -sancov 11 -callsite-splitting 53 -instcombine 95 -name-anon-globals 12 -called-value-propagation 54 -instnamer 96 -nary-reassociate 13 -canonicalize-aliases 55 -jump-threading 97 -newgvn 14 -consthoist 56 -lcssa 98 -pgo-memop-opt 15 -constmerge 57 -licm 99 -partial-inliner 16 -constprop 58 -libcalls-shrinkwrap 100 -partially-inline-libcalls 17 -coro-cleanup 59 -load-store-vectorizer 101 -post-inline-ee-instrument 18 -coro-early 60 -loop-data-prefetch 102 -functionattrs 19 -coro-elide 61 -loop-deletion 103 -mem2reg 20 -coro-split 62 -loop-distribute 104 -prune-eh 21 -correlated-propagation 63 -loop-fusion 105 -reassociate 22 -cross-dso-cfi 64 -loop-guard-widening 106 -redundant-dbg-inst-elim 23 -deadargelim 65 -loop-idiom 107 -rpo-functionattrs 24 -dce 66 -loop-instsimplify 108 -rewrite-statepoints-for-gc 25 -die 67 -loop-interchange 109 -sccp 26 -dse 68 -loop-load-elim 110 -slp-vectorizer 27 -reg2mem 69 -loop-predication 111 -sroa 28 -div-rem-pairs 70 -loop-reroll 112 -scalarizer 29 -early-cse-memssa 71 -loop-rotate 113 -separate-const-offset-from-gep 30 -early-cse 72 -loop-simplifycfg 114 -simple-loop-unswitch 31 -elim-avail-extern 73 -loop-simplify 115 -sink 32 -ee-instrument 74 -loop-sink 116 -speculative-execution 33 -flattencfg 75 -loop-reduce 117 -slsr 34 -float2int 76 -loop-unroll-and-jam 118 -strip-dead-prototypes 35 -forceattrs 77 -loop-unroll 119 -strip-debug-declare 36 -inline 78 -loop-unswitch 120 -strip-nondebug 37 -insert-gcov-profiling 79 -loop-vectorize 121 -strip 38 -gvn-hoist 80 -loop-versioning-licm 122 -tailcallelim 39 -gvn 81 -loop-versioning 123 -mergereturn 40 -globaldce 82 -loweratomic 41 -globalopt 83 -lower-constant-intrinsics Table 7.A list of LLVM compiler pass indices and their corresponding command line flag. Consistent * Complete* W ellDocumented*EasytoReuse* * Evaluated * CGO * Artifact * AEC Synthesizing Benchmarks for Predictive Modeling Chris Cummins Pavlos Petoumenos University of Edinburgh, UK {c.cummins,ppetoume}@inf.ed.ac.uk Zheng Wang Lancaster University, UK z.wang@lancaster.ac.uk Hugh Leather University of Edinburgh, UK hleather@inf.ed.ac.uk Abstract Predictive modeling using machine learning is an effective method for building compiler heuristics, but there is a short- age of benchmarks. Typical machine learning experiments outside of the compilation field train over thousands or mil- lions of examples. In machine learning for compilers, how- ever, there are typically only a few dozen common bench- marks available. This limits the quality of learned models, as they have very sparse training data for what are often high-dimensional feature spaces. What is needed is a way to generate an unbounded number of training programs that finely cover the feature space. At the same time the generated programs must be similar to the types of programs that human developers actually write, otherwise the learning will target the wrong parts of the feature space. We mine open source repositories for program fragments and apply deep learning techniques to automatically con- struct models for how humans write programs. We sample these models to generate an unbounded number of runnable training programs. The quality of the programs is such that even human developers struggle to distinguish our generated programs from hand-written code. We use our generator for OpenCL programs, CLgen, to automatically synthesize thousands of programs and show that learning over these improves the performance of a state of the art predictive model by 1.27×. In addition, the fine covering of the feature space automatically exposes weaknesses in the feature design which are invisible with the sparse training examples from existing benchmark suites. Correcting these weaknesses further increases performance by 4.30×. Categories and Subject Descriptors D.3.4 [ Program- ming Languages]: Processors—code generation, compilers, optimization Keywords Synthetic program generation, OpenCL, Bench- marking, Deep Learning, GPUs 1. Introduction Predictive modeling is a well researched method for building optimization heuristics that often exceed human experts and Ad-hoc Drivers clsmithclsmithDatasets clsmithclsmithTraining Programs Feature Extractor clsmithclsmithTraining Data Predictive Model Parameters Features Performance measurements Figure 1. Training a predictive model. reduces development time [1–11]. Figure 1 shows the process by which these models are trained. A set of training programs are identified which are expected to be representative of the application domain. The programs are compiled and executed with different parameter values for the target heuristic, to de- termine which are the best values for each training program. Each program is also summarized by a vector of features which describe the information that is expected to be impor- tant in predicting the best heuristic parameter values. These training examples of program features and desired heuristic values are used to create a machine learning model which, when given the features from a new, unseen program, can predict good heuristic values for it. It is common for feature vectors to contain dozens of elements. This means that a large volume of training data is needed to have an adequate sampling over the feature space. Without it, the machine learned models can only capture the coarse characteristics of the heuristic, and new programs which do not lie near to training points may be wrongly predicted. The accuracy of the machine learned heuristic is thus limited by the sparsity of the training points. There have been efforts to solve this problem using tem- plates. The essence of the approach is to construct a prob- abilistic grammar with embedded semantic actions that de- fines a language of possible programs. New programs may be created by sampling the grammar and, through setting proba- bilities on the grammar productions, the sampling is biased towards producing programs from one part of the space or an- other. This technique is potentially completely general, since a grammar can theoretically be constructed to match any de- sired program domain. However, despite being theoretically possible, it is not easy to construct grammars which are both suitably general and also produce programs that are in any 978-1-5090-4931-8/17 c⃝ 2017 IEEE CGO 2017, Austin, USA Accepted for publication by IEEE.c⃝ 2017 IEEE. Personal use of this material is permitted. Permission from IEEE must be obtained for all other uses, in any current or future media, including reprinting/ republishing this material for advertising or promotional purposes, creating new collective works, for resale or redistribution to servers or lists, or reuse of any copyrighted component of this work in other works. 86 way similar to human written programs. It has been shown to be successful over a highly restricted space of stencil bench- marks with little control flow or program variability [4, 8]. But, it is not clear how much effort it will take, or even if it is possible for human experts to define grammars capable of producing human like programs in more complex domains. By contrast, our approach does not require an expert to define what human programs look like. Instead, we automat- ically infer the structure and likelihood of programs over a huge corpus of open source projects. From this corpus, we learn a probability distribution over sets of characters seen in human written code. Later, we sample from this distribu- tion to generate new random programs which, because the distribution models human written code, are indistinguish- able from human code. We can then populate our training data with an unbounded number of human like programs, covering the space far more finely than either existing bench- mark suites or even the corpus of open source projects. Our approach is enabled by two recent developments: The first is the breakthrough effectiveness of deep learning for modeling complex structure in natural languages [12, 13]. As we show, deep learning is capable not just of learning the macro syntactical and semantic structure of programs, but also the nuances of how humans typically write code. It is truly remarkable when one considers that it is given no prior knowledge of the syntax or semantics of the language. The second is the increasing popularity of public and open platforms for hosting software projects and source code. This popularity furnishes us with the thousands of programming examples that are necessary to feed into the deep learning. These open source examples are not, sadly, as useful for directly learning the compiler heuristics since they are not presented in a uniform, runnable manner, nor do they typically have extractable test data. Preparing each of the thousands of open source projects to be directly applicable for learning compiler heuristics would be an insurmountable task. In addition to our program generator, CLgen, we also provide an accompanying host driver which generates datasets for, then executes and profiles synthesized programs. We make the following contributions: • We are the first to apply deep learning over source codes to synthesize compilable, executable benchmarks. • A novel tool CLgen 1 for general-purpose benchmark synthesis using deep learning. CLgen automatically and rapidly generates thousands of human like programs for use in predictive modeling. • We use CLgen to automatically improve the performance of a state of the art predictive model by1.27×, and expose limitations in the feature design of the model which, after correcting, further increases performance by 4.30×. 1https://github.com/ChrisCummins/clgen Rodinia NVIDIA SDK AMD SDK Parboil NAS Polybench SHOC Ad-hoc ISPASS Ploybench Lonestar SPEC-Viewperf MARS GPGPUsim 0 1 2 3 4 5 6 7 #. benchmarks used Figure 2. The average number of benchmarks used in GPGPU research papers, organized by origin. In this work we use the seven most popular benchmark suites. 2. Motivation In this section we make the argument for synthetic bench- marks. We identified frequently used benchmark suites in a survey of 25 research papers in the field of GPGPU perfor- mance tuning from four top tier conferences between 2013– 2016: CGO, HiPC, PACT, and PPoPP. We found the average number of benchmarks used in each paper to be 17, and that a small pool of benchmarks suites account for the majority of results, shown in Figure 2. We selected the 7 most frequently used benchmark suites (accounting for 92% of results), and evaluated the performance of the state of the art Grewe et al. [14] predictive model across each. The model predicts whether running a given OpenCL kernel on the GPU gives better performance than on the CPU. We describe the full experimental methodology in Section 7. Table 1 summarizes our results. The performance of a model trained on one benchmark suite and used to predict the mapping for another suite is generally very poor. The bench- mark suite which provides the best results, NVIDIA SDK, achieves on average only 49% of the optimal performance. The worst case is when training with Parboil to predict the optimal mappings for Polybench, where the model achieves only 11.5% of the optimal performance. From this it is clear that heuristics learned on one benchmark suite fail to general- ize across other suites. This problem is caused both by the limited number of benchmarks contained in each suite, and the distribution of benchmarks within the feature space. Figure 3 shows the fea- ture space of the Parboil benchmark suite, showing whether, for each benchmark, the model was able to correctly predict the appropriate optimization. We used Principle Component Analysis to reduce the multi-dimensional feature space to aid visualization. As we see in Figure 3a, there is a dense cluster of neigh- boring benchmarks, a smaller cluster of three benchmarks, and two outliers. The lack of neighboring observations means that the model is unable to learn a good heuristic for the two outliers, which leads to them being incorrectly optimized. In 87 AMD NPB NVIDIA Parboil Polybench Rodinia SHOC AMD - 38.0% 74.5% 76.7% 21.7% 45.8% 35.9% NPB 22.7% - 45.3% 36.7% 13.4% 16.1% 23.7% NVIDIA 29.9% 37.9% - 21.8% 78.3% 18.1% 63.2% Parboil 89.2% 28.2% 28.2% - 41.3% 73.0% 33.8% Polybench 58.6% 30.8% 45.3% 11.5% - 43.9% 12.1% Rodinia 39.8% 36.4% 29.7% 36.5% 46.1% - 59.9% SHOC 42.9% 71.5% 74.1% 41.4% 35.7% 81.0% - Table 1. Performance relative to the optimal of the Grewe et al. predictive model across different benchmark suites on an AMD GPU. The columns show the suite used for training; the rows show the suite used for testing. Principle Component 1 → Principle Component 2 → Correct Incorrect (a) Principle Component 1 → Principle Component 2 → Correct Incorrect Additional (b) Figure 3. A two dimensional projection of the Grewe et al. feature space, showing predictive model results over Parboil benchmarks on an NVIDIA GPU. Two outliers in (a) are incorrectly predicted due to the lack of nearby observations. The addition of neighboring observations in (b) corrects this. Figure 3b, we hand-selected benchmarks which are neigh- bouring in the feature space and retrained the model. The addition of these observations (and the information they pro- vide about that part of the feature space) causes the two outliers to be correctly optimized. We found such outliers in all of the benchmark suites of Table 1. These results highlight the significant effect that the num- ber and distribution of training programs has on the quality of predictive models. Without good coverage of the feature space, any machine learning methodology is unlikely to pro- duce high quality heuristics, suitable for general use on ar- bitrary real applications, or even applications from different benchmark suites. Our novel approach, described in the next section, solves this problem by generating an unbounded number of programs to cover the feature space with fine granularity. 3. Overview of Our Approach In this paper we present CLgen, a tool for synthesizing OpenCL benchmarks, and an accompanying host driver for executing synthetic benchmarks for gathering performance data for predictive modeling. While we demonstrate our approach using OpenCL, it is language agnostic. Our tool CLgen learns the semantics and structure from over a million lines of hand-written code from GitHub, and synthesizes programs through a process of iterative model sampling. CLgen Host Driver Language Corpus GitHub Software Repositories clsmithclsmithContent Files Rejection Filter Search engine Code Rewriter Model parameters Rejection Filter LSTM network Synthesizer Synthesis parameters Argument Extractor Benchmark parameters clsmithclsmithSynthesized Benchmarks Benchmark Driver clsmithclsmithSynthesized Payloads clsmithclsmithPerformance Results Dynamic Checker Figure 4. Benchmark synthesis and execution pipeline. We use a host driver to execute the synthesized programs to gather performance data for use in predictive modeling. Figure 4 provides an overview of the program synthesis and execution pipeline. Our approach extends the state of the art by providing a general-purpose solution for benchmark synthesis, leading to better and more accurate predictive models. In the course of evaluating our technique against prior work we discovered that it is also useful for evaluating the quality of features. Since we are able to cover the space so much more finely than the prior work, which only used standard benchmark suites, we are able to find multiple programs with identical feature values but different best heuristic values. This indicates that the features are not sufficiently discriminative and should be extended with more information to allow those programs to be separated. We go on to show that doing this significantly increases the performance of the learned heuristics. We expect that our technique will be valuable for feature designers. 88 4. CLgen: Benchmark Synthesis CLgen is an undirected, general-purpose program synthesizer for OpenCL. It adopts and augments recent advanced tech- niques from deep learning to learn over massive codebases. In contrast to existing grammar and template based approaches, CLgen is entirely probabilistic. The systemlearns to program using neural networks which model the semantics and usage of a huge corpus of code fragments in the target programming language. This section describes the assembly of an OpenCL language corpus, the application of deep learning over this corpus, and the process of synthesizing programs. 4.1 An OpenCL Language Corpus Deep learning requires large datasets [15]. For the purpose of modeling a programming language, this means assembling a very large collection of real, hand-written source codes. We assembled OpenCL codes by mining public repositories on the popular code hosting site GitHub. This is itself a challenging task since OpenCL is an embedded language, meaning device code is often difficult to untangle since GitHub does not presently recognize it as a searchable programming language. We developed a search engine which attempts to identify and download standalone OpenCL files through a process of file scraping and recursive header inlining. The result is a 2.8 million line dataset of 8078 “content files” which potentially contain OpenCL code, originating from 793 GitHub repositories. We prune the raw dataset extracted from GitHub using a custom toolchain we developed for rejection filtering and code rewriting, built on LLVM. Rejection Filter The rejection filter accepts as input a content file and returns whether or not it contains compilable, executable OpenCL code. To do this we attempt to compile the input to NVIDIA PTX bytecode and perform static analysis to ensure a minimum static instruction count of three. We discard any inputs which do not compile or contain fewer than three instructions. During initial development it became apparent that isolat- ing the OpenCL device code leads to a higher-than-expected discard rate (that is, seemingly valid OpenCL files being rejected). Through analyzing 148k lines of compilation er- rors, we discovered a large number of failures caused by undeclared identifiers — a result of isolating device code — 50% of undeclared identifier errors in the GitHub dataset were caused by only 60 unique identifiers. To address this, we developed a shim header which contains inferred values for common type definitions (e.g. FLOAT_T), and common constants (e.g. WGSIZE), shown in Listing 1. Injecting the shim decreases the discard rate from 40% to 32%, responsible for an additional 88k lines of code in the final language corpus. The resulting dataset is 2.0 million lines of compilable OpenCL source code. 1 / * Enable OpenCL f e a t u r e s * / 2 # d e f i n e c l _ c l a n g _ s t o r a g e _ c l a s s _ s p e c i f i e r s 3 # d e f i n e c l _ k h r _ f p 6 4 4 # i n c l u d e< c l c / c l c . h> 5 6 / * I n f e r r e d t y p e s * / 7 t y p e d e f f l o a t FLOAT_T ; 8 t y p e d e f unsigned i n t INDEX_TYPE ; . . . (36 more ) 9 10 / * I n f e r r e d c o n s t a n t s * / 11 # d e f i n e M_PI 3 . 1 40 2 5 12 # d e f i n e WG_SIZE 128 . . . (185 more ) Listing 1. The shim header file, providing inferred type aliases and constants for OpenCL on GitHub. Code Rewriter Programming languages have few of the issues of semantic interpretation present in natural language, though there remains many sources of variance at the syntac- tic level. For example, the presence and content of comments in code, and the choice of identifying names given to vari- ables. We consider these ambiguities to be non-functional variance, and developed a tool to normalize code of these variances so as to make the code more amenable to machine learning. This is a three step process: 1. The source is pre-processed to remove macros, conditional compilation, and source comments. 2. Identifiers are rewritten to have a short but unique name based on their order of appearance, using the sequential series {a, b, c, . . . , aa, ab, ac, . . .}for variables and {A, B, C, . . . , AA, AB, AC, . . .}for functions. This process isolates the syntactic structure of the code, and unlike prior work [16], our rewrite method preserves program behavior. Language built-ins (e.g. get_global_id, asin) are not rewritten. 3. A variant of the Google C++ code style is enforced to ensure consistent use of braces, parentheses, and white space. An example of the code rewriting process is shown in Figure 5. A side effect of this process is a reduction in code size, largely due to the removal of comments and excess white space. The final language corpus contains 1.3 million lines of transformed OpenCL, consisting of 9487 kernel functions. Identifier rewriting reduces the bag-of-words vocabulary size by 84%. 4.2 Learning OpenCL Generating valid, executable program code is an ambitious and challenging goal for unsupervised machine learning. We employ state of the art deep language modeling techniques to achieve this task. We use the Long Short-Term Memory (LSTM) architec- ture of Recurrent Neural Network [17, 18] to learn a character- level language model over the corpus of OpenCL compute kernels. The LSTM network architecture comprises recurrent 89 1 # d e f i n eDTYPE f l o a t 2 # d e f i n eALPHA( a ) 3 . 5 f * a 3 i n l i n e DTYPE ax (DTYPE x ) { return ALPHA( x ) ; } 4 5 _ _ k e r n e l void saxpy ( / * SAXPY k e r n e l * / 6 _ _ g l o b a l DTYPE * i n p u t 1 , 7 _ _ g l o b a l DTYPE * i n p u t 2 , 8 c o n s t i n t nelem ) 9 { 10 unsigned i n t i d x = g e t _ g l o b a l _ i d ( 0 ) ; 11 / / = ax + y 12 i f ( i d x < nelem ) { 13 i n p u t 2 [ i d x ] += ax ( i n p u t 1 [ i d x ] ) ; }} (a) Example content file 1 i n l i n e f l o a t A( f l o a t a ) { 2 return 3 . 5 f * a ; 3 } 4 5 _ _ k e r n e l void B( _ _ g l o b a l f l o a t* b , _ _ g l o b a l f l o a t* c , ↪→ c o n s t i n t d ) { 6 unsigned i n t e = g e t _ g l o b a l _ i d ( 0 ) ; 7 8 i f ( e < d ) { 9 c [ e ] += A( b [ e ] ) ; 10 } 11 } (b) Content file after code rewriting Figure 5. The code rewriting process, which transforms code to make it more amenable to language modeling. layers of memory cells, each consisting of an input, output, and forget gate, and an output layer providing normalized probability values from a 1-of-K coded vocabulary [19]. We use a 3-layer LSTM network with 2048 nodes per layer, implemented in Torch. We train this 17-million parameter model using Stochastic Gradient Descent for 50 epochs, using an initial learning rate of 0.002, decaying by a factor of one half every 5 epochs. Training took three weeks on a single machine using an NVIDIA GTX Titan, with a final model size of 648MB. Training the network is a one-off cost, and can be parallelized across devices. The trained network can be deployed to lower-compute machines for use. 4.3 Synthesizing OpenCL We synthesize OpenCL compute kernels by iteratively sam- pling the learned language model. We implemented two modes for model sampling: the first involves providing an ar- gument specification, stating the data types and modifiers of all kernel arguments. When an argument specification is pro- vided, the model synthesizes kernels matching this signature. In the second sampling mode this argument specification is omitted, allowing the model to synthesize compute kernels of arbitrary signatures, dictated by the distribution of argument types within the language corpus. In either mode we generate a seed text, and sample the model, character by character, until the end of the compute kernel is reached, or until a predetermined maximum number of characters is reached. Algorithm 1 illustrates this process. Algorithm 1 Sampling a candidate kernel from a seed text. Require: LSTM model M, maximum kernel length n. Ensure: Completed sample string S. 1: S ←“__kernel void A(const int a) {” Seed text 2: d ←1 Initial code block depth 3: for i ←|S|to n do 4: c ←predictcharacter(M, S) Generate new character 5: if c =“{” then 6: d ←d + 1 Entered code block, increase depth 7: else if c =“}” then 8: d ←d −1 Exited code block, decrease depth 9: end if 10: S ←S + c Append new character 11: if depth = 0then 12: break Exited function block, stop sampling 13: end if 14: end for The same rejection filter described in Section 4.1 then either accepts or rejects the sample as a candidate synthetic bench- mark. Listing 6 shows three examples of unique compute kernels generated in this manner from an argument specifi- cation of three single-precision floating-point arrays and a read-only signed integer. We evaluate the quality of synthe- sized code in Section 6. 5. Benchmark Execution We developed a host driver to gather performance data from synthesized CLgen code. The driver accepts as input an OpenCL kernel, generates payloads of user-configurable sizes, and executes the kernel using the generated payloads, providing dynamic checking of kernel behavior. 5.1 Generating Payloads A payload encapsulates all of the arguments of an OpenCL compute kernel. After parsing the input kernel to derive argument types, a rule-based approach is used to generate synthetic payloads. For a given global size Sg: host buffers of Sg elements are allocated and populated with random values for global pointer arguments, device-only buffers of Sg elements are allocated for local pointer arguments, integral arguments are given the valueSg, and all other scalar arguments are given random values. Host to device data transfers are enqueued for all non-write-only global buffers, and all non-read-only global buffers are transferred back to the host after kernel execution. 5.2 Dynamic Checker For the purpose of performance benchmarking we are not interested in the correctness of computed values, but we define a class of programs as performing useful work if they predictably compute some result. We devised a low-overhead runtime behavior check to validate that a synthesized program does useful work based on the outcome of four executions of a tested program: 90 1 _ _ k e r n e l void A( _ _ g l o b a l f l o a t* a , 2 _ _ g l o b a l f l o a t* b , 3 _ _ g l o b a l f l o a t* c , 4 c o n s t i n t d ) { 5 i n t e = g e t _ g l o b a l _ i d ( 0 ) ; 6 f l o a t f = 0 . 0 ; 7 f o r ( i n t g = 0 ; g < d ; g ++) { 8 c [ g ] = 0 . 0 f ; 9 } 10 b a r r i e r ( 1 ) ; 11 12 a [ g e t _ g l o b a l _ i d ( 0 ) ] = 2 *b [ g e t _ g l o b a l _ i d ( 0 ) ] ; 13 } (a) Vector operation with branching and synchronization. 1 _ _ k e r n e l void A( _ _ g l o b a l f l o a t* a , 2 _ _ g l o b a l f l o a t* b , 3 _ _ g l o b a l f l o a t* c , 4 c o n s t i n t d ) { 5 i n t e = g e t _ g l o b a l _ i d ( 0 ) ; 6 i f ( e >= d ) { 7 return ; 8 } 9 c [ e ] = a [ e ] + b [ e ] + 2 * a [ e ] + b [ e ] + 4 ; 10 } (b) Zip operation which computes ci = 3ai + 2bi + 4. 1 _ _ k e r n e l void A( _ _ g l o b a l f l o a t* a , 2 _ _ g l o b a l f l o a t* b , 3 _ _ g l o b a l f l o a t* c , 4 c o n s t i n t d ) { 5 unsigned i n t e = g e t _ g l o b a l _ i d ( 0 ) ; 6 f l o a t 1 6 f = ( f l o a t 1 6) ( 0 . 0 ) ; 7 f o r ( unsigned i n t g = 0 ; g < d ; g ++) { 8 f l o a t 1 6 h = a [ g ] ; 9 f . s0 += h . s0 ; 10 f . s1 += h . s1 ; 11 f . s2 += h . s2 ; 12 f . s3 += h . s3 ; 13 f . s4 += h . s4 ; 14 f . s5 += h . s5 ; 15 f . s6 += h . s6 ; 16 f . s7 += h . s7 ; 17 f . s8 += h . s8 ; 18 f . s9 += h . s9 ; 19 f . sA += h . sA ; 20 f . sB += h . sB ; 21 f . sC += h . sC ; 22 f . sD += h . sD ; 23 f . sE += h . sE ; 24 f . sF += h . sF ; 25 } 26 b [ e ] = f . s0 + f . s1 + f . s2 + f . s3 + f . s4 + f . s5 + ↪→ f . s6 + f . s7 + f . s8 + f . s9 + f . sA + f . sB + ↪→ f . sC + f . sD + f . sE + f . sF ; 27 } (c) Partial reduction over reinterpreted vector type. Figure 6. Compute kernels synthesized with CLgen. All three kernel were synthesized from the same argument spec- ification: three single-precision floating-point arrays and a read-only signed integer. 1. Create 4 equal size payloads A1in, B1in, A2in, B2in, subject to restrictions: A1in = A2in, B1in = B2in, A1in ̸= B1in. 2. Execute kernel k 4 times: k(A1in) →A1out, k(B1in) → B1out, k(A2in) →A2out, k(B2in) →B2out. 3. Assert: • A1out ̸= A1in and B1out ̸= B1in, else k has no output (for these inputs). • A1out ̸= B1out and A2out ̸= B2out, else k is input insensitive t (for these inputs). • A1out = A2out and B1out = B2out, else k is non- deterministic. Equality checks for floating point values are performed with an appropriate epsilon to accommodate rounding errors, and a timeout threshold is also used to catch kernels which are non-terminating. Our method is based on random differential testing [20], though we emphasize that this is not a general purpose approach and is tailored specifically for our use case. For example, we anticipate a false positive rate for kernels with subtle sources of non-determinism which more thorough methods may expose [21–23], however we deemed such methods unnecessary for our purpose of performance modeling. 6. Evaluation of Synthetic Programs In this section we evaluate the quality of programs synthe- sized by CLgen by their likeness to hand-written code, and discuss limitations of the synthesis and execution pipeline. 6.1 Likeness to Hand-written Code Judging whether a piece of code has been written by a human is a challenging task for a machine, so we adopt a methodology from machine learning research based on the Turing Test [24–26]. We reason that if the output of CLgen is human like code, then a human judge will be unable to distinguish it from hand-written code. We devised a double blind test in which 15 volunteer OpenCL developers from industry and academia were shown 10 OpenCL kernels each. Participants were tasked with judging whether, for each kernel, they believed it to have been written by hand or by machine. Kernels were randomly selected for each participant from two equal sized pools of synthetically generated and hand-written code from GitHub. We applied the code rewriting process to all kernels to remove comments and ensure uniform identifier naming. The participants were divided into two groups, with 10 of them receiving code generated by CLgen, and 5 of them acting as a control group, receiving code generated by CLSmith [27], a program generator for differential testing1. We scored each participant’s answers, finding the average score of the control group to be 96% (stdev. 9%), an unsurpris- 1An online version of this test is available at http://humanorrobot.uk/. 91 Raw Code Features comp static #. compute operations mem static #. accesses to global memory localmem static #. accesses to local memory coalesced static #. coalesced memory accesses transfer dynamic size of data transfers wgsize dynamic #. work-items per kernel (a) Individual code features Combined Code Features F1: transfer/(comp+mem) commun.-computation ratio F2: coalesced/mem % coalesced memory accesses F3: (localmem/mem)×wgsize ratio local to global mem accesses ×#. work-items F4: comp/mem computation-mem ratio (b) Combinations of raw features Table 2. Grewe et al. model features. ing outcome as generated programs for testing have multiple “tells”, for example, their only input is a singleulong pointer. There were no false positives (synthetic code labeled human) for CLSmith, only false negatives (human code labeled syn- thetic). With CLgen synthesized programs, the average score was 52% (stdev. 17%), and the ratio of errors was even. This suggests that CLgen code is indistinguishable from hand- written programs, with human judges scoring no better than random chance. 6.2 Limitations Our new approach enables the synthesis of more human-like programs than current state of the art program generators, and without the expert guidance required by template based generators, but it has limitations. Our method of seeding the language models with the start of a function means that we cannot support user defined types, or calls to user-defined functions. This means that we only consider scalars and ar- rays as inputs; while 6 (2.3%) of the benchmark kernels from Table 3 use irregular data types as inputs. We will address this limitation through recursive program synthesis, whereby a call to a user-defined function or unrecognized type will trigger candidate functions and type definitions to be synthe- sized. Currently we only run single-kernel benchmarks. We will extend the host driver to explore multi-kernel schedules and interleaving of kernel executions. Our host driver gener- ates datasets from uniform random distributions, as do many of the benchmark suites. For cases where non-uniform in- puts are required (e.g. profile-directed feedback), an alternate methodology for generating inputs must be adopted. 7. Experimental Methodology 7.1 Experimental Setup Predictive Model We reproduce the predictive model from Grewe, Wang, and O’Boyle [14]. The predictive model is used to determine the optimal mapping of a given OpenCL kernel to either a GPU or CPU. It uses supervised learning to construct a decision tree with a combination of static and Version #. benchmarks #. kernels NPB (SNU [29]) 1.0.3 7 114 Rodinia [30] 3.1 14 31 NVIDIA SDK 4.2 6 12 AMD SDK 3.0 12 16 Parboil [31] 0.2 6 8 PolyBench [32] 1.0 14 27 SHOC [33] 1.1.5 12 48 Total - 71 256 Table 3. List of benchmarks. Intel CPU AMD GPU NVIDIA GPU Model Core i7-3820 Tahiti 7970 GTX 970 Frequency 3.6 GHz 1000 MHz 1050 MHz #. Cores 4 2048 1664 Memory 8 GB 3 GB 4 GB Throughput 105 GFLOPS 3.79 TFLOPS 3.90 TFLOPS Driver AMD 1526.3 AMD 1526.3 NVIDIA 361.42 Compiler GCC 4.7.2 GCC 4.7.2 GCC 5.4.0 Table 4. Experimental platforms. dynamic kernel features extracted from source code and the OpenCL runtime, detailed in Table 2b. Benchmarks As in [14], we test our model on the NAS Parallel Benchmarks (NPB) [28]. We use the hand-optimized OpenCL implementation of Seo, Jo, and Lee [29]. In [14] the authors augment the training set of the predictive model with 47 additional kernels taken from 4 GPGPU benchmark suites. To more fully sample the program space, we use a much larger collection of 142 programs, summarized in Table 3. These additional programs are taken from all 7 of the most frequently used benchmark suites identified in Section 2. None of these programs were used to train CLgen. We synthesized 1,000 kernels with CLgen to use as additional benchmarks. Platforms We evaluate our approach on two 64-bit CPU- GPU systems, detailed in Table 4. One system has an AMD GPU and uses OpenSUSE 12.3; the other is equipped with an NVIDIA GPU and uses Ubuntu 16.04. Both platforms were unloaded. Datasets The NPB and Parboil benchmark suites are pack- aged with multiple datasets. We use all of the packaged datasets (5 per program in NPB, 1-4 per program in Par- boil). For all other benchmarks, the default datasets are used. We configured the CLgen host driver to synthesize payloads between 128B-130MB, approximating that of the dataset sizes found in the benchmark programs. 7.2 Methodology We replicated the methodology of [14]. Each experiment is repeated five times and the average execution time is recorded. The execution time includes both device compute time and the data transfer overheads. We use leave-one-out cross-validation to evaluate predic- tive models. For each benchmark, a model is trained on data from all other benchmarks and used to predict the mapping 92 1 _ _ k e r n e l void A( _ _ g l o b a l f l o a t* a , 2 _ _ g l o b a l f l o a t* b , 3 _ _ g l o b a l f l o a t* c , 4 c o n s t i n t d ) { 5 i n t e = g e t _ g l o b a l _ i d ( 0 ) ; 6 i f ( e < 4 & & e < c ) { 7 c [ e ] = a [ e ] + b [ e ] ; 8 a [ e ] = b [ e ] + 1 ; 9 } 10 } Listing 2. In the Grewe et al. feature space this CLgen program is indistinguishable from AMD’s Fast Walsh–Hadamard transform benchmark, but has very different runtime behavior and optimal device mapping. The addition of a branching feature fixes this. for each kernel and dataset in the excluded program. We re- peat this process with and without the addition of synthetic benchmarks in the training data. We do not test model predic- tions on synthetic benchmarks. 8. Experimental Results We evaluate the effectiveness of our approach on two hetero- geneous systems. We first compare the performance of a state of the art predictive model [14] with and without the addi- tion of synthetic benchmarks, then show how the synthetic benchmarks expose weaknesses in the feature design and how these can be addressed to develop a better model. Finally we compare the ability of CLgen to explore the program feature space against a state of the art program generator [27]. 8.1 Performance Evaluation Figure 7 shows speedups of the Grewe et al. predictive model over the NAS Parallel Benchmark suite with and without the addition of synthesized benchmarks for training. Speedups are calculated relative to the best single-device mapping for each experimental platform, which is CPU-only for AMD and GPU-only for NVIDIA. The fine grained coverage of the feature space which synthetic benchmarks provide improves performance dramatically for the NAS benchmarks. Across both systems, we achieve an average speedup of 2.42× with the addition of synthetic benchmarks, with prediction improvements over the baseline for 62.5% of benchmarks on AMD and 53.1% on NVIDIA. The strongest performance improvements are on NVIDIA with the FT benchmark which suffers greatly under a single- device mapping. However, the performance on AMD for the same benchmark slightly degrades after adding the synthetic benchmarks, which we address in the next section. 8.2 Extending the Predictive Model Feature designers are bound to select as features only prop- erties which are significant for the sparse benchmarks they test on, which can limit a model’s ability to generalize over a wider range of programs. We found this to be the case with the Grewe et al. model. The addition of automatically gener- ated programs exposed two distinct cases where the model failed to generalize as a result of overspecializing to the NPB suite. The first case is thatF3 is sparse on many programs. This is a result of the NPB implementation’s heavy exploitation of lo- cal memory buffers and the method by which they combined features (we speculate this was a necessary dimensionality reduction in the presence of sparse training programs). To counter this we extended the model to use the raw feature values in addition to the combined features. The second case is that some of our generated programs had identical feature values as in the benchmark set, but had different behavior (i.e. optimal mappings). Listing 2 shows one example of a CLgen benchmark which is indistinguish- able in the feature space to one the of existing benchmarks — the Fast Walsh-Hadamard transform — but with different behavior. We found this to be caused by the lack of dis- criminatory features for branching, since the NPB programs are implemented in a manner which aggressively minimized branching. To counter this we extended the predictive model with an additional feature containing a static count of branch- ing operations in a kernel. Figure 8 shows speedups of our extended model across all seven of the benchmark suites used in Section 2. Model performance, even on this tenfold increase of benchmarks, is good. There are three benchmarks on which the model per- forms poorly: MatrixMul, cutcp, and pathfinder. Each of those programs make heavy use of loops, which we be- lieve the static code features of the model fail to capture. This could be addressed by extracting dynamic instruction counts using profiling, but we considered this beyond the scope of our work. It is not our goal to perfect the predictive model, but to show the performance improvements associated with training on synthetic programs. To this extent, we are suc- cessful, achieving average speedups of 3.56×on AMD and 5.04×on NVIDIA across a very large test set. 8.3 Comparison of Source Features As demonstrated in Section 2, the predictive quality of a model for a given point in the feature space is improved with the addition of observations from neighboring points. By producing thousands of artificial programs modeled on the structure real OpenCL programs, CLgen is able to consis- tently and automatically generate programs which are close in the feature space to the benchmarks which we are testing on. To quantify this effect we use the static code features of Table 2a, plus the branching feature discussed in the previous subsection, to measure the number of CLgen kernels generated with the same feature values as those of the benchmarks we examined in the previous subsections. We examine only static code features to allow comparison with the GitHub kernels for which we have no automated method to execute them and extract runtime features, and CLSmith generated programs. 93 BT.A BT.B BT.S BT.W CG.A CG.B CG.C CG.S CG.W EP.A EP.B EP.C EP.W FT.A FT.B FT.S FT.W LU.A LU.B LU.C LU.S LU.W MG.A MG.B MG.C MG.S MG.W SP.A SP.B SP.C SP.S SP.W Average 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 Speedup over CPU Grewe et al. w. CLgen (a) AMD Tahiti 7970 BT.A BT.B BT.S BT.W CG.A CG.B CG.C CG.S CG.W EP.A EP.B EP.C EP.W FT.A FT.B FT.S FT.W LU.A LU.B LU.C LU.S LU.W MG.A MG.B MG.C MG.S MG.W SP.A SP.B SP.C SP.S SP.W Average 1 3 5 7 9 11 13 15 17 Speedup over GPU Grewe et al. w. CLgen (b) NVIDIA GTX 970 Figure 7. Speedup of programs using Grewe et al. predictive model with and without synthetic benchmarks. The predictive model outperforms the best static device mapping by a factor of 1.26×on AMD and 2.50×on NVIDIA. The addition of synthetic benchmarks improves the performance to 1.57×on AMD and 3.26×on NVIDIA. Figure 9 plots the number of matches as a function of the number of kernels. Out of 10,000 unique CLgen kernels, more than a third have static feature values matching those of the benchmarks, providing on average 14 CLgen kernels for each benchmark. This confirms our original intuition: CLgen kernels, by emulating the way real humans write OpenCL programs, are concentrated in the same area of the feature space as real programs. Moreover, the number of CLgen kernels we generate is unbounded, allowing us to continually refine the exploration of the feature space, while the number of kernels available on GitHub is finite. CLSmith rarely produces code similar to real-world OpenCL programs, with only 0.53% of the generated kernels have matching feature values with benchmark kernels. We conclude that the unique contribution of CLgen is its ability to generate many thousands of programs that are appropriate for predictive modeling. 9. Related Work Our work lies at the intersections of a number of areas: pro- gram generation, benchmark characterization, and language modeling and learning from source code. There is no existing work which is similar to ours, in respect to learning from large corpuses of source code for benchmark generation. GENESIS [34] is a language for generating synthetic train- ing programs. Users annotate template programs with sta- tistical distributions over features, which are instantiated to generate statistically controlled permutations of templates. Template based approaches provide domain-specific solutions for a constrained feature and program space, for example, gen- erating permutations of Stencil codes [35, 36]. Our approach provides general-purpose program generation over unknown domains, in which the statistical distribution of generated programs is automatically inferred from real world code. Random program generation is an effective method for software testing. Grammar-based fuzz testers have been de- veloped for C [37] and OpenCL [27]. A mutation-based ap- proach for the Java Virtual Machine is demonstrated in [38]. Goal-directed program generators have been used for a vari- ety of domains, including generating linear transforms [39], MapReduce programs [40], and data structure implementa- tions [41]. Program synthesis from input/output examples is used for simple algorithms in [42], string manipulation in [43], and geometry constructions in [44]. Machine learning has been applied to source code to aid software engineering. Naturalize employs techniques devel- oped in the natural language processing domain to model cod- ing conventions [45]. JSNice leverages probabilistic graphical models to predict program properties such as identifier names for Javascript [46]. 94 Figure 8. Speedups of predictions using our extended model over Grewe et al. on both experimental platforms. Synthetic benchmarks and the additional program features outperform the original predictive model by a factor3.56×on AMD and 5.04× on NVIDIA. 0 2000 4000 6000 8000 10000 #. kernels 0 500 1000 1500 2000 2500 3000 3500 #. matches GitHub CLSmith CLgen Figure 9. The number of kernels from GitHub, CLSmith, and CLgen with static code features matching the bench- marks. CLgen generates kernels that are closer in the feature space than CLSmith, and can continue to do so long after we have exhausted the extent of the GitHub dataset. Error bars show standard deviation of 10 random samplings. There is an increasing interest in mining source code repos- itories at large scale [16, 47, 48]. Previous studies have in- volved data mining of GitHub to analyze software engineer- ing practices [49–52], for example code generation [53], code summarization [54], comment generation [55], and code com- pletion [56]. However, no work so far has exploited mined source code for benchmark generation. This work is the first to do so. 10. Conclusion The quality of predictive models is bound by the quantity and quality of programs used for training, yet there is typically only a few dozen common benchmarks available for experi- ments. We present a novel tool which is the first of it’s kind — an entirely probabilistic program generator capable of gen- erating an unbounded number of human like programs. Our approach applies deep learning over a huge corpus of publicly available code from GitHub to automatically infer the seman- tics and practical usage of a programming language. Our tool generates programs which to trained eyes are indistinguish- able from hand-written code. We tested our approach using a state of the art predictive model, improving its performance by a factor of 1.27×. We found that synthetic benchmarks exposed weaknesses in the feature set which, when corrected, further improved the performance by 4.30×. Our hope for this work is to demonstrate a proof of concept for an exciting new avenue of program generation, and that the full release of CLgen will expedite discovery in other domains. In future work we will extend the approach to multiple programming languages, and investigate methods for performing an auto- matic directed search of feature spaces. Acknowledgments Our thanks to the volunteers at Codeplay Software Ltd and the University of Edinburgh for participating in the qual- itative evaluation. This work was supported by the UK Engineering and Physical Sciences Research Council un- der grants EP/L01503X/1 (CDT in Pervasive Parallelism), EP/L000055/1 (ALEA), EP/M01567X/1 (SANDeRs), EP/M0 15823/1, and EP/M015793/1 (DIVIDEND). The code and data for this paper are available at: http://chriscummins.cc/cgo17. 95 References [1] P. Micolet, A. Smith, and C. Dubach. “A Machine Learning Approach to Mapping Streaming Workloads to Dynamic Multicore Processors”. In: LCTES. 2016. [2] Z. Wang, G. Tournavitis, B. Franke, and M. O’Boyle. “Integrating Profile-driven Parallelism Detection and Machine-learning-based Mapping”. In: TACO (2014). [3] A. Magni, C. Dubach, and M. O’Boyle. “Automatic Optimization of Thread-Coarsening for Graphics Pro- cessors”. In: PACT. ACM, 2014, pp. 455–466. [4] C. Cummins, P. Petoumenos, M. Steuwer, and H. Leather. “Towards Collaborative Performance Tuning of Algorithmic Skeletons”. In: HLPGPU. 2016. [5] Z. Wang and M. O’Boyle. “Mapping Parallelism to Multi-cores: A Machine Learning Based Approach”. In: PPoPP. 15. ACM, 2009, pp. 75–84. [6] Y . Wen, Z. Wang, and M. O’Boyle. “Smart Multi- Task Scheduling for OpenCL Programs on CPU/GPU Heterogeneous Platforms”. In: HiPC. IEEE, 2014. [7] Z. Wang and M. O’Boyle. “Partitioning Streaming Parallelism for Multi-cores: A Machine Learning Based Approach”. In: PACT. ACM, 2010, pp. 307–318. [8] T. L. Falch and A. C. Elster. “Machine Learning Based Auto-tuning for Enhanced OpenCL Performance Porta- bility”. In: IPDPSW. IEEE, 2015. [9] A. Collins, C. Fensch, and H. Leather. “Auto-Tuning Parallel Skeletons”. In: Parallel Processing Letters 22.02 (June 2012), p. 1240005. [10] H. Leather, E. Bonilla, and M. O’Boyle. “Automatic Feature Generation for Machine Learning Based Opti- mizing Compilation”. In: TACO 11 (2014). [11] W. F. Ogilvie, P. Petoumenos, Z. Wang, and H. Leather. “Fast Automatic Heuristic Construction Using Active Learning”. In: LCPC. 2014. [12] A. Graves. “Generating Sequences with Recurrent Neural Networks”. In: arXiv:1308.0850 (2013). [13] I. Sutskever, O. Vinyals, and Q. V . Le. “Sequence to Sequence Learning with Neural Networks”. In: NIPS. 2014. [14] D. Grewe, Z. Wang, and M. O’Boyle. “Portable Map- ping of Data Parallel Programs to OpenCL for Hetero- geneous Systems”. In: CGO. IEEE, 2013. [15] Y . LeCun, Y . Bengio, and G. Hinton. “Deep learning”. In: Nature 521.7553 (2015), pp. 436–444. [16] M. Allamanis and C. Sutton. “Mining Source Code Repositories at Massive Scale using Language Model- ing”. In: MSR. 2013, pp. 207–216. [17] M. Sundermeyer, R. Schl, and H. Ney. “LSTM Neural Networks for Language Modeling”. In: Interspeech. 2012. [18] T. Mikolov. “Recurrent Neural Network based Lan- guage Model”. In: Interspeech. 2010. [19] A. Graves and J. Schmidhuber. “Framewise Phoneme Classification with Bidirectional LSTM and Other Neural Network Architectures”. In: Neural Networks 5.5 (18), pp. 602–610. [20] W. M. McKeeman. “Differential Testing for Software”. In: DTJ 10.1 (1998), pp. 100–107. [21] A. Betts, N. Chong, and A. Donaldson. “GPUVerify: A Verifier for GPU Kernels”. In:OOPSLA. 2012, pp. 113– 131. [22] J. Price and S. Mcintosh-Smith. “Oclgrind: An Exten- sible OpenCL Device Simulator”. In: IWOCL. ACM, 2015. [23] T. Sorensen and A. Donaldson. “Exposing Errors Re- lated to Weak Memory in GPU Applications”. In:PLDI. 2016. [24] H. Gao, J. Mao, J. Zhou, Z. Huang, L. Wang, and W. Xu. “Are You Talking to a Machine? Dataset and Methods for Multilingual Image Question Answering”. In: arXiv:1505.05612 (2015). [25] R. Zhang, P. Isola, and A. A. Efros. “Colorful Image Colorization”. In: arXiv:1603.08511 (2016). [26] O. Vinyals, A. Toshev, S. Bengio, and D. Erhan. “Show and Tell: A Neural Image Caption Generator”. In: CVPR (2015). [27] C. Lidbury, A. Lascu, N. Chong, and A. Donald- son. “Many-Core Compiler Fuzzing”. In:PLDI. 2015, pp. 65–76. [28] D. H. Bailey, E. Barszcz, J. Barton, D. Browning, R. Carter, L. Dagum, R. Fatoohi, S. Fineberg, P. Frederick- son, T. Lasinski, R. Schreiber, H. Simon, V . Venkatakr- ishnan, and S. Weeratunga. “The NAS Parallel Bench- marks”. In: IJHPCA 5.3 (1991), pp. 63–73. [29] S. Seo, G. Jo, and J. Lee. “Performance Characteriza- tion of the NAS Parallel Benchmarks in OpenCL”. In: IISWC. IEEE, 2011. [30] S. Che, M. Boyer, J. Meng, D. Tarjan, J. W. Sheaffer, S. H. Lee, and K. Skadron. “Rodinia: A Benchmark Suite for Heterogeneous Computing”. In:IISWC. IEEE, Oct. 2009. [31] J. A. Stratton, C. Rodrigues, I. Sung, N. Obeid, L. Chang, N. Anssari, G. D. Liu, and W. W. Hwu. “Par- boil: A Revised Benchmark Suite for Scientific and Commercial Throughput Computing”. In: Center for Reliable and High-Performance Computing (2012). [32] S. Grauer-Gray, L. Xu, R. Searles, S. Ayalasomayajula, and J. Cavazos. “Auto-tuning a High-Level Language Targeted to GPU Codes”. In:InPar. 2012. [33] A. Danalis, G. Marin, C. McCurdy, J. S. Meredith, P. C. Roth, K. Spafford, V . Tipparaju, and J. S. Vetter. “The Scalable HeterOgeneous Computing (SHOC) Bench- mark Suite”. In: GPGPU. ACM, 2010. 96 [34] A. Chiu, J. Garvey, and T. S. Abdelrahman. “Genesis: A Language for Generating Synthetic Training Programs for Machine Learning”. In: CF. ACM, 2015, p. 8. [35] J. D. Garvey and T. S. Abdelrahman. “Automatic Per- formance Tuning of Stencil Computations on GPUs”. In: ICPP (2015). [36] C. Cummins, P. Petoumenos, M. Steuwer, and H. Leather. “Autotuning OpenCL Workgroup Size for Stencil Patterns”. In: ADAPT. 2016. [37] X. Yang, Y . Chen, E. Eide, and J. Regehr. “Finding and Understanding Bugs in C Compilers”. In: PLDI. 2011. [38] Y . Chen, T. Su, C. Sun, Z. Su, and J. Zhao. “Coverage- Directed Differential Testing of JVM Implementations”. In: PLDI. 2016. [39] Y . V oronenko, F. De Mesmay, and M. Püschel. “Com- puter Generation of General Size Linear Transform Libraries”. In: CGO. IEEE, 2009, pp. 102–113. [40] C. Smith. “MapReduce Program Synthesis”. In:PLDI. 2016. [41] C. Loncaric, T. Emina, and M. D. Ernst. “Fast Synthesis of Fast Collections”. In: PLDI. 2016. [42] W. Zaremba, T. Mikolov, A. Joulin, and R. Fergus. “Learning Simple Algorithms from Examples”. In: ICML. 2016. [43] S. Gulwani. “Automating string processing in spread- sheets using input-output examples”. In: POPL. 2011. [44] S. Gulwani, V . A. Korthikanti, and A. Tiwari. “Synthe- sizing geometry constructions”. In: PLDI. 2011. [45] M. Allamanis, E. T. Barr, C. Bird, and C. Sutton. “Learning Natural Coding Conventions”. In:FSE. 2014, pp. 281–293. [46] Veselin Raychev, Martin Vechev, and Andreas Krause. “Predicting Program Properties from “Big Code””. In: POPL. 2015. [47] M. White, C. Vendome, M. Linares-Vasquez, and D. Poshyvanyk. “Toward Deep Learning Software Reposi- tories”. In: MSR. 2015. [48] E. Kalliamvakou, L. Singer, G. Gousios, D. M. German, K. Blincoe, and D. Damian. “The Promises and Perils of Mining GitHub”. In: MSR. 2009. [49] Y . Wu, J. Kropczynski, P. C. Shih, and J. M. Car- roll. “Exploring the Ecosystem of Software Develop- ers on GitHub and Other Platforms”. In: CSCW. 2014, pp. 265–268. [50] E. Guzman, D. Azócar, and Y . Li. “Sentiment Analysis of Commit Comments in GitHub: an Empirical Study”. In: MSR. 2014, pp. 352–355. [51] R. Baishakhi, D. Posnett, V . Filkov, and P. Devanbu. “A Large Scale Study of Programming Languages and Code Quality in Github”. In: FSE. 2014. [52] B. Vasilescu, V . Filkov, and A. Serebrenik. “Percep- tions of Diversity on GitHub: A User Survey”. In: Chase (2015). [53] X. Gu, H. Zhang, D. Zhang, and S. Kim. “Deep API Learning”. In: arXiv:1605.08535 (2016). [54] M. Allamanis, H. Peng, and C. Sutton. “A Convolu- tional Attention Network for Extreme Summarization of Source Code”. In: arXiv:1602.03001 (2016). [55] E. Wong, J. Yang, and L. Tan. “AutoComment: Mining Question and Answer Sites for Automatic Comment Generation”. In: ASE. IEEE, 2013, pp. 562–567. [56] V . Raychev, M. Vechev, and E. Yahav. “Code Com- pletion with Statistical Language Models”. In: PLDI. 2014. 97 A. Artifact description A.1 Abstract Our research artifact consists of interactive Jupyter notebooks. For your convenience, we provide two methods of validating our results: an ‘AE’ notebook which validates the main exper- iments of the paper, and a comprehensive ‘Paper’ notebook which replicates every experiment of the paper, including additional analysis. The most convenient method to evaluate our results is to access our pre-configured live server: http://[redacted]:8888/notebooks/AE.ipynb using the password [redacted], and to follow the instruc- tions contained within. A.2 Description A.2.1 Check-list (Artifact Meta Information) • Run-time environment: A web browser. • Output: OpenCL code, runtimes, figures and tables from the paper. • Experiment workflow: Run (or install locally) Jupyter note- books; interact with and observe results. • Experiment customization: Edit code in Jupyter notebook; full API and CLI for CLgen. • Publicly available?: Yes, code and data. See: http://chriscummins.cc/cgo17/ A.2.2 How Delivered Jupyter notebooks which contain an annotated version of this paper, interleaved with the code necessary to replicate results. We provide three options to run the Jupyter notebooks: 1. Remote access to the notebook running on our pre- configured experimental platform. 2. Download our pre-packaged VirtualBox image with Jupyter notebook installed. 3. Install the project locally on your own machine. A.3 Installation Access the Jupyter notebooks using one of the three methods we provide. Once accessed, proceed to Section A.4. A.3.1 Remote Access The Jupyter notebooks are available at: http://[redacted]:8888, password [redacted]. A dashboard showing server load is available at: http://[redacted]:19999 High system load may lead to inconsistent performance results; this may occur if multiple reviewers are accessing the server simultaneously. A.3.2 Virtual Machine Copy our pre-configured 5.21 GB VirtualBox image using: $ scp cgo@[redacted]:vm.ova ~ Password: [redacted] Install the virtual machine using VirtualBox’s “Import Appli- ance” command: The image was prepared using VirtualBox 5.1.8. It has the following configuration: Ubuntu 16.04, 4 GB RAM, 10 GB hard drive, bridged network adapter with DHCP, US keyboard layout, GMT timezone. Start the machine and log in using username and password cgo. Once at the shell, runlaunch. This will start the Jupyter notebook server and print its address. You can access the notebooks at this address using the browser of the host device. Please note that the VirtualBox image does not have OpenCL, so new runtimes cannot be generated. A.3.3 Local Install See http://chriscummins.cc/cgo17/ for instructions. Note that we only support Ubuntu 16.04 or OS X, and sudo privileges are required to install the necessary requirements. Other Linux distributions may work but will require extra steps to install the correct package versions. 98 A.4 Experiment Workflow 1. Access the Jupyter notebook server using one of the three options described in Section A.3. 2. From the Jupyter server page, tick the checkbox next to one of the two notebooks: AE.ipynb for minimal arti- fact reproduction or Paper.ipynb for a comprehensive interactive paper. 3. Click the button “Duplicate”. 4. Click on the name of the newly created copy, e.g. Paper-Copy1.ipynb or AE-Copy3.ipynb. 5. Repeatedly press theplay button (tooltip is “run cell, select below”) to step through each cell of the notebook. OR select “Kernel” > “Restart & Run All” from the menu to run all of the cells in order. A.5 Evaluation and Expected Result Each code cell within the Jupyter notebook generates an output. Expected results are described in text cells. We include both the code necessary to evaluate the data used in the paper, and the code necessary to generate and evaluate new data. For example, we include the large neural network trained on all of the OpenCL on GitHub (which took 3 weeks to train), along with a small dataset to train a new one. A.6 Experiment Customization The experiments are fully customizable. The Jupyter note- book can be edited “on the fly”. Simply type your changes into the cells and re-run them. For example, in Table 1 of the Paper.ipyn notebook we cross-validate the performance of predictive models on an AMD GPU: To replicate this experiment using the NVIDIA GPU, change the first line of the appropriate code cell to read data = nvidia_benchmarks and re-run the cell: Note that some of the cells depend on the values of prior cells and must be executed in sequence. CLgen has a documented API and command line interface. You can create new corpuses, train new networks, sample kernels, etc. A.7 Notes For more information about CLgen, visit: http://chriscummins.cc/clgen For more information about Artifact Evaluation, visit: http://ctuning.org/ae/submission-20161020.html 99 A DEEP LEARNING BASED COST MODEL FOR AUTOMATIC CODE OPTIMIZATION Riyadh Baghdadi1 2 Massinissa Merouani3 Mohamed-Hicham Leghettas3 Kamel Abdous3 Taha Arbaoui4 Karima Benatchba3 Saman Amarasinghe1 ABSTRACT Enabling compilers to automatically optimize code has been a longstanding goal for the compiler community. Efficiently solving this problem requires using precise cost models. These models predict whether applying a sequence of code transformations reduces the execution time of the program. Building an analytical cost model to do so is hard in modern x86 architectures due to the complexity of the microarchitecture. In this paper, we present a novel deep learning based cost model for automatic code optimization. This model was integrated in a search method and implemented in the TIRAMISU compiler to select the best code transformations. The input of the proposed model is a set of simple features representing the unoptimized code and a sequence of code transformations. The model predicts the speedup expected when the code transformations are applied. Unlike previous models, the proposed one works on full programs and does not rely on any heavy feature engineering. The proposed model has only 16% of mean absolute percentage error in predicting speedups on full programs. The proposed model enables TIRAMISU to automatically find code transformations that match or are better than state-of-the-art compilers without requiring the same level of heavy feature engineering required by those compilers. 1 I NTRODUCTION Writing high-performance software is essential in many ar- eas from machine learning to science and engineering. In nuclear physics, for example, researchers need to perform large scale simulations to study the properties of matter. A highly optimized implementation of these simulations can be orders of magnitude faster compared to an unop- timized implementation. In deep learning, an optimized implementation of a state-of-the-art neural network such as XLNet (Yang et al., 2019) is 1.8× faster than the equivalent PyTorch implementation. Writing such a highly optimized code requires ninja programmers and is time-consuming while the results are error-prone, less understandable, and non-portable. One of the longstanding goals in the compiler community is to develop compilers that can automatically optimize high-level code. These compilers automatically apply code transformations to make the code run faster; thus, avoiding the need for manual low-level program tun- ing. They provide greater productivity, portability, and high performance, and will be directly accessible by domain scientists. 1Massachusetts Institute of Technology 2New York Univer- sity Abu Dhabi 3Ecole Nationale Superieure d’Informatique 4University of Technology of Troyes. Correspondence to: Riyadh Baghdadi . Proceedings of the4 th MLSys Conference, San Jose, CA, USA, 2021. Copyright 2021 by the author(s). Automatically generating efficient code for high- performance systems is a tedious task. In order for the compiler to generate efficient code, two problems have to be solved. First, a large set of code transformations and a mechanism to apply them to programs need to be provided. Examples of such transformations include loop fission, fusion, parallelization, and vectorization. Second, the right sequence of code transformations from this large set has to be chosen. The selected code transformations must preserve the program semantics and provide the highest performance for the input program. While state-of-the-art-compilers have shown success in solving the first problem (i.e., the ability to provide a large set of transformations and correctly apply a selected sequence of transformations (Wolf & Lam, 1991; Bondhugula et al., 2008; Trifunovic et al., 2010; Grosser et al., 2014; Lefebvre & Feautrier, 1998; Quiller´e & Rajopadhye, 2000)), they still do not successfully solve the second problem (i.e., selecting the sequence of transformations that will provide the best performance). The problem of selecting the right sequence of code trans- formations can be modeled as a search problem that can be solved in three steps. In the first step, the compiler uses a search technique to explore the space of possible code transformations. The result of this step is a set of candidates where each one is a sequence of code transformations. In the second step, the compiler checks the validity of each candidate (i.e., checks that applying the transformations A Deep Learning Based Cost Model for Automatic Code Optimization does not change the program semantics). In the third step, the compiler evaluates the valid candidates and chooses the one that minimizes the execution time. This evaluation can be done by running each candidate on the target hardware to obtain the exact speedup. However, this is not a feasible solution in practice as running a program takes a consider- able amount of time. Moreover, the target hardware may not be available at compile time. Another way to evaluate a candidate is by using a cost model to predict the speedup. Designing cost models manually is known to be a hard task (Trifunovic et al., 2009; Bachir et al., 2013). This is mainly due to the diversity of hardware architectures and their complexity (out-of-order execution, complex memory hierarchies, data prefetching, etc.). Complex interactions be- tween code transformations make the problem more compli- cated. Recently, cost models, such as Ithemal (Mendis et al., 2018) and Halide (Adams et al., 2019), have demonstrated how to overcome some of this complexity by using deep learning. While these state-of-the-art cost models are more accurate, they are limited in two ways: Ithemal (Mendis et al., 2018) only predicts throughput for basic blocks of as- sembly code (instead of full programs). It also assumes that data is always in cache. The cost model in Halide (Adams et al., 2019) requires heavy feature engineering (it uses 54 complex program features). Designing such features is te- dious, error-prone, and time-consuming. In this paper, we propose a novel DNN-based cost model that avoids the problems of previous work. Our model op- erates on full programs expressed in a high-level language (not just basic blocks). It takes into consideration not only memory accesses to the cache but also to the main memory. Moreover, it does not require heavy feature engineering. The proposed cost model takes the original unoptimized code and a sequence of code transformations and predicts the speedup that these transformations would yield when applied. The model is designed for CPUs and is integrated in the TIRAMISU compiler (Baghdadi et al., 2019), a com- piler for the TIRAMISU domain-specific language (DSL). Because this model is a regression model, it allows the com- piler to select the best transformation candidates by ranking the candidates selected by a search technique. Contributions In summary, the contributions of this pa- per are: • A novel deep-learning-based cost model for code opti- mization. This cost model is a regression cost model, operates on full programs, and does not rely on extract- ing complex features. • An implementation of the proposed model and an inte- gration into a search approach to enable the TIRAMISU compiler to automatically search for the best code trans- formations. • We evaluate the proposed model and show that it has a low error rate reaching 16% mean absolute percent- age error. We show also that it enables TIRAMISU to automatically find code transformations that match or outperform state-of-the-art compilers. 2 T IRAMISU EMBEDDED DSL TIRAMISU (Baghdadi et al., 2019) is a domain-specific lan- guage (DSL) embedded in C++. It provides a C++ API that allows users to write a high level, architecture-independent algorithm, and a set of API calls to select which code trans- formations should be applied. The first part of a TIRAMISU program specifies the algorithm without specifying how it should be optimized. The second part specifies which code transformations to apply and how the results of computa- tions should be stored. TIRAMISU uses a mathematical model known as the polyhedral model internally (Feautrier, 1988; Baghdadi et al., 2015a; Bondhugula et al., 2008; Bagh- dadi et al., 2015b; 2019) to represent code, code transfor- mations, and to reason about the correctness of code trans- formations. The following code shows an example of a convolution algorithm written in TIRAMISU . 1 // Declare the iterators. 2 var n(0, batch), fout(0, out_features), fin (0, in_features), y(0, H-2), x(0, W-2), k0(0, 3), k1(0, 3); 3 // Algorithm. 4 conv(n, fout, y, x) += weights(fout, fin, y , x) * input(n, fin, y + k0, x + k1); The iterators in line 2 define the loop bounds around the conv computation. The algorithm is semantically equiva- lent to the following code. 1 for (n in 0..batch) 2 for (fout in 0..out_features) 3 for (y in 0..H-2) 4 for (x in 0..W-2) 5 for (fin in 0..in_features) 6 for (k0 in 0..3) 7 for (k1 in 0..3) 8 conv[n, fout, y, x] += weigths[fout, fin, y, x] * input[n, fin, y+k0, x+k1]; The next code shows an example of code transformation commands that can be applied to the previous convolution kernel. These commands apply parallelization, loop inter- change, tiling, vectorization, and unrolling. 1 // Provide the code transformation commands. 2 conv.parallelize(n); 3 conv.interchange(fout, fin); 4 conv.tile(y, x, 32, 32); 5 conv.vectorize(fout, 8); 6 conv.unroll(k0); conv.unroll(k1); Currently, in TIRAMISU , a developer has to provide the previous sequence of code transformations manually. Our A Deep Learning Based Cost Model for Automatic Code Optimization goal is to automate finding that sequence. We do this by developing a cost model that predicts the speedup of using a given transformation or any sequence of valid transfor- mations. For example, the model can be used to predict whether combining parallelization, loop interchange, and loop tiling is useful. In addition, the model can be used to choose the right arguments for each one of the previous code transformations (e.g., choose the tile sizes). 3 D ATA GENERATION As training DNNs requires a large data set and only a small number of programs have ever been written in TIRAMISU , we decided to automatically generate a data set and use it to train the model. We developed a code generator that generates random programs and sequences of code transfor- mations. Each one of these randomly generated programs and code transformations is compiled, executed, and finally, the actual speedup is measured. The speedup is the ratio between the execution time of the original unoptimized pro- gram and the optimized one. Each data point in the data set is a triplet of the form (program, a sequence of code transformations, measured speedup). Random Code Generation A TIRAMISU program is a sequence of computations where each computation is an as- signment. There are three common patterns of assignments that appear in TIRAMISU programs: (1) simple assignments where the right-hand side is a function of input arrays or array values computed previously; (2) stencils; (3) reduc- tions. The random code generator generates sequences of computations where each computation is a variant (or a combination) of the previous patterns. Randomly generated programs are correct by construction. A computation con- sumes either constants, input arrays, or values computed by previous computations. Code transformations are also generated randomly but specific rules are used to guarantee that code transformations are valid (for example, tiling is not applied if the loop extent is smaller than the tile size). The random code generator is designed to generate programs that are representative of real programs. The three patterns that the random code generator generates, when combined together, cover all the patterns that we are interested in supporting. The input data is also generated automatically and the size of the input data is chosen randomly. Since the generated programs are not data dependent (no data dependent conditional or data dependent array access), the actual data values are not important. Only the size of the data is important for training the model. For a given randomly generated program, the random code generator chooses random data sizes, and then generates 32 random sequences of code transformations. Dataset Construction The total generated dataset has ap- proximately 1.8 million programs. To construct this dataset, we generated 56250 random algorithms. For each algorithm, we generated 32 random sequences of code transformations. Therefore we obtained 56250 × 32 programs in total. We followed the gold-standard in performance engineering and executed each resulting program 30 times, and retained the median value of the execution times in order to reduce the impact of minor variance in execution times. Since data generation is time consuming, we used a cluster of 16 nodes of multicore CPUs to accelerate data generation. Generating the whole data set took 3 weeks. 4 P ROGRAM CHARACTERIZATION AND MODEL ARCHITECTURES Our cost model is designed to support programs that can be expressed in TIRAMISU . The latter is designed for express- ing data parallel algorithms that operate over dense arrays using loop nests and sequences of statements. These algo- rithms are often found in image processing, deep learning, dense linear algebra, tensor operations, and stencil com- putations. A formal description of programs supported by TIRAMISU can be found in (Baghdadi et al., 2019; 2020). Code transformations supported by the proposed model in- clude loop fusion, loop tiling, loop interchange, and loop unrolling which are all challenging. For simpler transfor- mations such as parallelization and vectorization, we use simple heuristics similar to those used by the Halide au- toscheduler (Ragan-Kelley et al., 2012). These heuristics mainly parallelize the outermost loops and vectorize the innermost loops when a set of conditions are met. 4.1 Program Characterization Designing complex hand-engineered features is tedious, error-prone, and time-consuming. Instead of using com- plex hand-engineered features, we characterize programs by extracting simple high-level information that is stored in a compact variable-size representation. Our program characterization is based on the AST (Abstract Syntax Tree) representation of programs. A program is characterized as an ordered tree of computation vectors as shown in Figure 1b. A computation vectoris a vector that includes three pieces of information: (1) loop nest representation; (2) assignments representation; (3) loop transformation representation. In the following paragraphs, we describe each of these components, the key features we aim to encode by each one, and how we combine them in a compact way. Loop Nest Representation The extent of each loop level around the computation is stored in the computation vector (the extent of a loop is calculated based on its lower and up- per bounds). An example is shown in Figure 1c. After each loop level extent, for each loop transformation, we insert a boolean tag that represents whether that transformation is A Deep Learning Based Cost Model for Automatic Code Optimization for i: for j: for k: computation A for l: computation B for m: for n: computation C computation D computation E Loop i j k l m n Computation A B C D E Computation Vector E Loop Nest VectorAssignment Vector Loop i Loop j Loop m Transformations applied on loop i Transformations applied on loop j Transformations applied on loop m Memory access 1 Memory access 2 Memory access n Operations count Memory access 3 (a) Program pseudocode. (b) Program tree representation. (c) Computation vector. Figure 1: Our characterization of a typical program. applied to that particular loop level. Each transformation is followed by its parameters (when this applies). Assignments Representation We represent both the left- hand side and the right-hand side of the assignment. To represent the left-hand side, we store the dimensions and the size of each dimension of the buffer used on the left-hand side. To represent the right-hand side of the assignment (the assignment expression), we store the following information: (1) the memory access pattern (access matrix described later); (2) the ID of each accessed buffer (a number); (3) the count of each arithmetic operation used on the right-hand side (i.e., the number of times each arithmetic operation is used). We represent the array accesses using an access matrix that stores the coefficients of each array access. This matrix uses exactly the same format used in the polyhedral model to represent array accesses (Paul & Christian, 2011). It only supports arrays that have affine array accesses (i.e., array accesses that are affine in the loop iterators). Supporting only affine accesses is not a problem since TIRAMISU only supports code that has affine accesses. Supporting code that has data-dependent array accesses or non-affine accesses is not within the scope of this paper. The access matrix has k rows and n + 1columns where k is the number of dimensions of the access buffer and n is the loop depth. Each row in the matrix represents an array dimension. Each array dimension is considered to be a linear combination of the loop iterators. Each loop iterator in the matrix is represented by a column. The coefficient of each loop iterator is stored in the column that corresponds to that loop iterator. The last column in the matrix corresponds to constants. M =   1 0 0 1 1 0 0 1 −2   For example, the following memory access A[i0, i0 + i1, i1 − 2] is represented using the matrix M. In this case, the first dimension of the buffer access is i0. It can also be written as 1∗i0 +0 ∗i1 +0. It is represented by the first row in the matrix using 1 0 0where the first column corresponds to iterator i0, the second column corresponds to i1 and the last column corresponds to constants. The second access i0 +i1 is represented with the second row in the matrix1 1 0. Each memory access matrixis succeeded by the identifier of the buffer. Loop Transformation Representation Each loop trans- formation can be characterized by two pieces of information: transformation type and its parameters. Since transforma- tions are applied on loop levels, we attach to the representa- tion of each loop level the transformations that are applied to that level (Figure 1c). The transformations that involve changing the structure of the program (e.g. loop fusion) are directly applied to the program structure representationthat we will describe next. Program Structure Representation The program is rep- resented as a tree structure where leaves are thecomputation vectors and internal nodes are the loop levels, as shown in Figure 1b. 4.2 Detailed List of Features Composing the Computation Vector Table 1 details the full list of features that constitute the Computation Vectorpresented in Figure 1c. All features are integer values except Tag features which are boolean values. In practice, we set n = 7and m = 21where n is the maximum length of the loop nests in our dataset and m is the maximum number of terms used in an assignment. When needed, a zero-padding is added to the Loop Nest Vector and Assignment Vector. 4.3 Hardware Characterization The goal of the paper is not to develop a hardware indepen- dent model. The proposed model is specific to a particular CPU. The user can build a model for each CPU they want to target. Building a new model does not require a large effort. It can be done simply by running a script that generates new data and retrains the model. A Deep Learning Based Cost Model for Automatic Code Optimization Loop Nest Vector Loop1 Upper bound, Lower bound, Reduction tag Fusion tag, Interchange tag, Tilling tag, Tilling factor Loop2 Upper bound, Lower bound, Reduction tag Fusion tag, Interchange tag, Tilling tag, Tilling factor ... ... Loopn Upper bound, Lower bound, Reduction tag Fusion tag, Interchange tag, Tilling tag, Tilling factor, Unroll tag, Unrolling factor. Assignment Vector Memory access 1 Access matrix, Buffer ID. Memory access 2 Access matrix, Buffer ID. ... ... Memory access m Access matrix, Buffer ID. Operations count Number of Additions, Number of Multiplications, Number of Subtractions, Number of Divisions. Table 1: A detailed listing of the features that compose the Computation Vector. In other words, we do not include any feature to repre- sent the hardware because the model is specific to one and only one hardware architecture. We also do not extract any hardware-specific feature from the code for the same rea- son. Designing a model that works for multiple hardware architectures is beyond the scope of this paper. 4.4 Model Architecture We model the problem of speedup estimation as a regression problem: given an algorithm and a set of code transforma- tions, our model predicts the speedup expected when ap- plying the suggested code transformations compared to the base program (i.e. without applying code transformations). We design our cost model’s architecture to support the vari- able size and recursive nature of our program characteri- zation by combining Recurrent and Recursive Neural Net- works. Our model’s architecture has three layers as shown in Figure 2a. Computation Embedding Layer All computation vec- tors of the program are processed through a feedforward network after log-transforming non-boolean features. This log-transformation is necessary since these features have a large dynamic range and most of them are expected to be multiplied with other features to compute the final speedup. Recursive Loop Embedding Layer The computation embeddings resulting from the previous layer are then pro- cessed recursively following the tree structure of the pro- gram using the loop embedding unit. At a given loop level, the loop embedding unit summarizes the program up to that loop into a loop embedding. The loop embedding unit, as depicted in Figure 2b, is composed of two separate LSTM cells (Hochreiter & Schmidhuber, 1997) and a feedforward layer. At each loop level, the first LSTM is fed with the embedding vectors of computations that are nested directly in that loop level while the second LSTM is fed with the embedding vectors of the previous loop levels that resulted from the previous loop embedding units. The two hidden states of the LSTMs are merged using a feedforward layer into a loop embedding vector. The purpose of this recursive embedding is to selectively in- corporate information from each computation respecting its positional relations with the other computations. The output of this layer, the program embedding vector, is assumed to contain the needed set of automatically extracted features covering the complete program. Regression Layer The program embedding vectorpro- duced by the previous layer is finally fed to a shallow feed- forward neural network that performs a regression in order to predict the speedup. We choose MAPE (Mean Absolute Percentage Error) as an objective function to train our model. The model is im- plemented in PyTorch (Paszke et al., 2019) and optimized using AdamW (Loshchilov & Hutter, 2017). All the imple- mentation details including layer sizes and training policy can be found in appendix A.1. Other Neural Network Models Explored We also ex- plored many other alternative architectures for the cost- model, the architecture presented above has the lowest MAPE error on both the test set and benchmarks set. For instance, replacing the Recursive loop embedding layerwith a simple Recurrent Neural Network that is directly fed with the sequence of computation embeddingswithout taking in consideration the loops hierarchy leads to a relative increase of 1.15x in MAPE of the test set and 1.33x in the bench- marks set compared to the presented architecture. Another straightforward choice of using a simple Feedforwad Neural Network, i.e. totally skipping the Recursive loop embedding A Deep Learning Based Cost Model for Automatic Code Optimization DC E A B C D E Computation embedding vector  Feedforward NN  Loop embedding unit Loop embedding vector  Feedforward NN  Computation vector  Recursive Loop Embedding Layer Regression Layer Computation Embedding Layer A B i j k l m n LSTM LSTM Child computation embeddings Child loop embeddings New loop embedding ŷ Predicted Speedup (a) Processing the program presented in Figure 1 through the three layers of the cost-model. (b) Loop embedding unit. Figure 2: The cost model architecture layer and feeding directly the concatenated computation em- beddings to the regression layer, leads to a relative increase of 1.39x in MAPE of the test set and 1.37x in the bench- marks set compared to the presented model. In addition, this alternative has the considerable limitation of not sup- porting variable program sizes and supports only programs that contain up to a certain number of computations (we have set the maximum number of computations to 4 when testing this alternative). 4.5 Level of Feature Extraction One of the questions that we needed to answer is at which level should the code representation be extracted: directly from the source code or from the transformed code (interme- diate representation obtained after applying code transfor- mations)? Our choice was to extract the representation from the TIRAMISU source code for a pragmatic reason. In order for a model that takes transformed code to work, Tiramisu will need to apply the transformations on the program before using the model. Such a step is time-consuming especially because it will be repeated a large number of times (given that the search space is large). Furthermore, transformed code is more complex and therefore is harder to learn from compared to a program and a list of transformations. 5 S EARCH SPACE EXPLORATION Finding the best code transformations is a hard combina- torial optimization problem due to the fact that some of the constraints (e.g., interaction between code transforma- tions), and the objective (the speedup in this case), are hard to represent mathematically using the program’s features. Thus, the proposed model is used as an objective function estimator to better navigate the search space. However, the used search exploration approach should take into account the estimator’s margin of error, thus requiring stochasticity in the search space exploration. Since the interaction between code transformations is hard to characterize, one of the best ways to model the problem of finding the best code transformations (and their parameters) is to use a tree search. This allows us to use classical tree search algorithms. In this paper, we use Beam Search and MCTS (Monte Carlo Tree Search). The Beam Search tree (as shown in Figure 3) explores whether to apply a code transformation and which parame- ters to use for that transformation. At each node of the tree, an evaluation is conducted using the cost model to assess whether the chosen transformations provide a good speedup. In Figure 3, exploring the tree shows that applying tiling with a tile size of (16, 8) and unrolling with a factor of 4 provides the best sequence of code transformations. MCTS takes advantage of the search tree and takes into account the stochasticity of the model. Particularly, the proposed MCTS combines our model’s prediction and an execution of the best evaluated code transformations as a compromise between prediction and execution. MCTS first explores the different branches of the tree and selects a number of promising code transformations. To this end, the model is used in each node to obtain an estimate of the speedup. MCTS keeps track of a set of the best evaluated code transformations to execute them (the size of the set is a parameter of the approach). Once the tree is explored, the set of the best code transformations is executed. The advantage of this two-step approach is to accelerate the exploration of the search space using the model and to correct the model’s error, if occurred, by executing a limited set of programs and their code transformations. The proposed model is thus A Deep Learning Based Cost Model for Automatic Code Optimization C yes no C.tile() C tile? Unroll? C.tile(16,8).unroll() C.tile(16,8) yes no C.tile(16,8).unroll(2) C.tile(16,8).unroll(4) 2 4 C.tile(8,8) C.tile(16,8) C.tile(32,8) 8,8 16,8 32,8 Parameters? Explore: tiling, unrolling Figure 3: Example of the BS Tree for exploring the tiling and unrolling code transformations used to prune the search space and limit the execution to selected code transformations. 6 E VALUATION To evaluate our cost model: (1) we measure its accuracy on a test set composed of random programs and compare the predicted and the measured speedups on that data set; (2) we measure the speedups obtained when the model is used to search for code transformations in real-world benchmarks; (3) we compare the accuracy of this model with the accuracy of the model used in Halide (Ragan-Kelley et al., 2012), a state-of-the-art model. The model evaluation and the data collection are performed on 16 identical multi-core CPU nodes. Each node has a dual-socket, each socket is a 12-core Intel Xeon E5-2680v3 CPU, with 128 GB RAM. We used 60% of data for training, 20% for validation, and 20% for testing. MAPE (y, ˆy) = 1 n n∑ i=1 ⏐⏐⏐yi − ˆyi yi ⏐⏐⏐ Model Accuracy To measure the accuracy of the pro- posed model, we use MAPE (Mean Absolute Percentage Error), where y and ˆy are respectively the measured and the predicted speedups. The MAPE of our cost model on the test set is 16%. The Pearson correlation coefficient for the proposed model is 0.90, showing that the linear correlation between pre- dicted and measured speedups is strong. In addition, we evaluate the ranking capabilities of the model with the Spear- man’s rank correlation coefficient, defined as: rs(y, ˆy) = r ( rg(y), rg(ˆy) ) where rg(y) converts the speedups to ranks and r is the Pearson correlation coefficient. The Spearman’s rank coefficient of our cost model is 0.95, which shows that the predicted and measured ranks are highly linearly correlated. This property is important when using the model with a search method. Comparing Predicted and Measured Speedups Fig- ure 4 compares the predicted and measured speedups. To simplify visualization, we use a subset of the test set. This subset is composed of 100 random programs, each with 32 random sequences of code transformations (therefore, the total is 3200 transformed programs). The horizontal axis is the list of 3200 programs. These programs are sorted based on their speedups in ascending order to simplify vi- sualization. As the figure shows, the predicted speedups are close to the measured ones. The error in prediction is lower around the speedup 1 and is higher as the speedup gets further from 1. We will comment more on this behavior later in the section. Figure 5 investigates the distribution of the model error rates over the whole test set. On top, Absolute Percentage Error (APE) is measured on the code transformations of each program and the results are plotted through a histogram. On bottom, APE is measured on all data points of the test set and the measured speedups are plotted against their APE. We can see that the error gets smaller as speedups approach 1 and gets higher as speedups get far from 1. Particularly, the error is more significant for speedups below 0.05. The model is more accurate around speedup 1 because most programs in the training data set have speedups close to 1. Speedups below 0.05 are less frequent. The next experiment will evaluate whether the accuracy of the model allows finding the best code transformations when searching the space. Search Space Exploration Using the Cost Model In this experiment, we evaluate the ability of search approach combined with the cost model to find good code transfor- mation sequences for real-world benchmarks. We use BS and MCTS to explore the search space. We use a set of real-world benchmarks spanning different areas: image pro- cessing, deep learning, linear algebra and stencils. The benchmarks include box blur (an image processing filter to blur images), conv + relu(two successive neural net- work layers that benefit from operator fusion), convolution (a direct neural network convolution), cvtcolor (an image processing filter for converting the colors of an input image from RGB to gray), doitgen (a kernel from the multiresolu- tion adaptive numerical scientific simulation (Louis-Noel, 2010)), heat2d (heat equation over 2D space), heat3d (heat equation over 3D space), jacobi2d (a jacobi-style stencil computation over 2D data with 5-point stencil pattern), mvt (matrix vector multiplication composed with another matrix vector multiplication but with transposed matrix), and sei- del2d (Gauss-Seidel style stencil computation over 2D data with 9-point stencil pattern). The sizes of the input data for each benchmark is provided in the appendix. Figure 6 shows the best speedups found for each benchmark. The baseline is the original program where the outermost A Deep Learning Based Cost Model for Automatic Code Optimization Transformed programs ordered by their speedups Speedup 0.005 0.01 0.05 0.1 0.5 1 5 10 50 100 Predicted speedup Measured speedup Figure 4: Predicted speedups compared to measured speedups. The speedups are ordered in ascending order. Absolute percentage error in predicted speedup Number of programs0 10000 20000 30000 40000 0.00 0.06 0.12 0.18 0.24 0.30 0.36 0.42 0.48 0.54 0.60 0.66 0.72 0.78 0.84 0.90 0.96 Measured speedup Absolute percentage error0% 10% 20% 30% 40% 0.05 0.1 0.5 1 5 10 Figure 5: The distribution of error rates for the whole test set. On top, APE is measured for each transformed program, then the histogram of measurements is plotted. On bottom, APE is measured for each transformed program, then the speedups are plotted with their APE. loop is parallelized (no other code transformation is applied). The first column (blue), reports results obtained when beam search is used to explore the search space. This column is considered the reference in our comparison as execution is used to obtain the speedups. In the second and third columns, beam search and MCTS use the cost model to predict speedups. The last column shows the speedups Speedup 0 1 2 3 4 5 6 7 8 box blur conv + reluconvolution cvtcolordoitgenheat2dheat3djacobi2d mvt seidel2d Beam search with execution Beam search with the cost model MCTS with the cost model Halide Autoscheduler Figure 6: Speedups for different benchmarks obtained by exploring the search space. obtained after applying the Halide autoscheduler (Halide automatic optimizer) defined in (Adams et al., 2019). Beam search (BS) with the cost model is competitive in most benchmarks, but does not find the best code transfor- mations in heat2d, jacobi2d and seidel2d. Beam search with the cost model relies entirely on predictions to make deci- sions. Bad predictions can thus mislead the search method which is why beam search does not find the best transfor- mations in the previous benchmarks. MCTS has similar performance, except in jacobi2d and seidel2d where it finds better code transformations, and in cvtcolor where the code transformations found are less good. MCTS can find bet- ter code transformations in these cases because it copes with model imprecision taking into account its stochasticity. However, since the tree space is explored differently, MCTS might explore different nodes compared to BS and thus have distinguishable results. A Deep Learning Based Cost Model for Automatic Code Optimization Comparison with Halide In this section, we compare our cost model with the one of Halide (Adams et al., 2019), a state-of-the-art cost model and the closest to ours. In comparison with Halide, TIRAMISU finds transformation sequences that are either competitive with those found by Halide or better (except in box blur). This is mainly due to miss predictions by the Halide model which lead Halide to use transformations that degrade performance. These wrong predictions happen in particular in benchmarks that are from the area of scientific computing which Halide was not trained to handle (heat2d, jacobi2d, mvt and seidel2d). In benchmarks that fall in the categories of deep learning and image processing, which Halide supports well, TIRAMISU and Halide have comparable performance. We also compare the performance of the Halide model with that of TIRAMISU on randomly generated programs. Halide’s paper usesR2 as an accuracy metric and uses MSE (Mean Square Error) as a loss function, we thus use the same metric and loss function for comparison. Halide has an R2 of 0.96, whereas TIRAMISU has 0.89. Both Halide and TIRAMISU have comparable results but Halide uses heavy feature engineering. The main advantage of TIRAMISU is that it does not require feature engineering. Tradeoff Between Search Time and Quality of Code Transformations It is crucial to note that the execution time of a search method is dependent on the time to evaluate code transformations. If one compiles and executes every transformed program to assess the speedup of code trans- formations, the search time would increase considerably and therefore becomes impractical. The proposed model accelerates the search space exploration, reducing thus the time needed to find the best code transformations. Table 2 illustrates the tradeoff that we make between the time needed to explore the search space, and the perfor- mance of the final code transformations found. It compares the gains from reducing the search time and performance degradation due to the use of a model. To be specific, for each benchmark: (1) we compare the time necessary to ex- plore the search space using Beam Search with Execution (BSE) and using either of Beam Search with the Cost Model (BSM) on the left table, or MCTS on the right table. Com- paring these two shows how faster BSM and MCTS are with regard to BSE. (2) we compare the performance of the final code transformations returned by BSE and the ones returned by BSM or MCTS. The second column of the table represents the speedup in search time (the time taken by BSE over the time taken by BSM or MCTS). The third column is the degradation in performance (execution time) of the code transformations found by BSM or MCTS compared to the code transforma- tions found by BSE. We can see that, on average, searching with BSM is 106.5 times faster than searching with BSE, while incurring an average decrease of 15% in the perfor- mance of the code transformations found. Moreover, search- ing with MCTS is 11.8 faster on average, with a loss of 12.5% in performance. Note that for jacobi2d in beam search, and cvtcolor in MCTS, the performance degradation is important. This is mainly due to the imprecision of the model for these benchmarks. The model predicts some bad code transfor- mations as being good. This is mainly because a pattern that appears in those benchmarks is not covered enough by the training data. A solution to this problem would be to generate more data that include the missing pattern. Pearson correlation 0.00 0.25 0.50 0.75 1.00 Spearman's rank correlation 0.00 0.25 0.50 0.75 1.00 Figure 7: Correlation between predicted and measured speedups for the data points in thesmall test set. Pearson correlation is on the left and Spearman’s correlation is on the right. Each column repre- sents the coefficient measured on 32 random code transformations for a single program. More Detailed Evaluation Figure 7 gives more insights on the behavior of our model. The Pearson and Spearman’s coefficients are measured on a subset of the test set between the code transformations of each program. To simplify visu- alization, we use the same subset of transformations as the experiment of Figure 4. In most cases, the coefficients are close to 1, highlighting a strong linear correlation between the predicted and measured speedups (Pearson correlation), and between the predicted and measured ranks (Spearman’s correlation). Particularly, the correlation between ranks is of most importance for search methods as these methods rely on the ranks of the explored points instead of their actual evaluations. 7 R ELATED WORK Several machine learning based cost models have been developed for automatic code optimization. MILEPOST GCC (Fursin et al., 2008) uses a 1-nearest-neighbor model that takes manually engineered features and predicts the best combinations of compiler flags for GCC (GNU Compiler Collection). Ithemal (Mendis et al., 2018) uses an LSTM based model to predict the throughput of basic blocks of the control-flow graph (assembly-level code). Both of MILE- POST GCC and Ithemal do not support high-level loop transformations though. Modeling loop transformations is in particular challenging as it requires the ability to model the loop structure. This implies the ability to model cycles in the control-flow graph of the program, which is not trivial. In addition, Ithemal does not model memory accesses to A Deep Learning Based Cost Model for Automatic Code Optimization Benchmark Search time improvement (speedup) Performance degradation for code transforma- tions box blur 65x 0 % conv + relu 12x 0 % convolution 9x 0 % cvtcolor 65x 7 % doitgen 114x 7 % heat2d 117x 18 % heat3d 351x 13 % jacobi2d 122x 65 % mvt 83x 12 % seidel2d 127x 28 % Average 106.5x 15 % Benchmark Search time improvement (speedup) Performance degradation for code transforma- tions box blur 19x 0 % conv + relu 14x 0 % convolution 11x 0 % cvtcolor 3x 41 % doitgen 12x 5 % heat2d 17x 17 % heat3d 28x 9 % jacobi2d 4x 26 % mvt 5x 9 % seidel2d 5x 18 % Average 11.8x 12.5 % Table 2: Search time improvement compared to performance degradation. On the left, the results for beam search with the cost model are shown, and on the right, the results for MCTS. different memory hierarchies (it only models accesses to cache). Unlike both systems, our proposed model supports loop transformations and takes into consideration different memory hierarchy levels. Other related work includes a model proposed by Rahman et al. (Rahman et al., 2010). This model uses a feedforward neural network to predict the execution time of programs af- ter applying the tiling code transformation. Another model proposed by Magni et al. (Magni et al., 2014) uses a feed- forward neural network in a cascade fashion to predict the best thread-coarsening factor. These two methods rely on hand-engineered features though. They are also limited to a single code transformation. Halide (Adams et al., 2019) proposes a more comprehensive method to find efficient code transformations. It combines beam search with a feedforward neural network that pre- dicts the execution time of programs from a set of manually- engineered features. It uses 54 heavily engineered features to perform its predictions. To the best of our knowledge, both of Tiramisu and Halide consider the same code trans- formations in their search spaces. In the same context, Au- toTVM (Chen et al., 2018) uses a deep learning model to search for code transformation parameters (TVM compares two models, a TreeGRU and a Gradient Boosted Tree). The TVM models are used with simulated annealing to search the space. The authors only demonstrate the search for trans- formation parameters though (tile size, unrolling factor, ...). They do not demonstrate search for loop transformations since the transformations themselves are provided by the user. In a different fashion, DeepTune (Cummins et al., 2017) proposes a neural network consisting of embedding layers and LSTM cells to predict whether an OpenCL kernel should be mapped to CPU or GPU. DeepTune also proposes another model to predict whether thread coarsening (a code transformation for GPUs) should be used. The DeepTune models are classification models though. This means that they can classify whether a given transformation is benefi- cial, but they are not designed to rank different sequences of code transformations. Therefore, they are not ideal for use when searching a large space of code transformations where many sequences need to be ranked and the best one selected. The goal of this paper is not to propose a cost model for general purpose compilers. The goal is also not to propose a cost model for general purpose transformations. In a way similar to related work, this paper mainly focuses on a domain specific compiler and on loop transformations. Many polyhedral compilers including Pluto (Bondhugula et al., 2008), PENCIL (Baghdadi et al., 2015a; 2013a), LLVM Poly (Grosser et al., 2012), and Tensor Compre- hensions (Vasilache et al., 2018) formalize the problem of automatic code optimization as an integer linear program (ILP). The objective of this ILP is to minimize the distance between producer and consumer statements. The resulting problem can be solved exactly, but the implicit cost model does not capture all the complexity of the hardware architec- ture and transformation interactions (Baghdadi et al., 2019). This leads to suboptimal solutions (Baghdadi et al., 2019; 2015a; 2013b). Making the objective function more compre- hensive makes the problem non-linear and thus it becomes intractable. 8 C ONCLUSION This paper presents a novel cost model for predicting speedups. This cost model is a regression cost model that operates on full programsand does not rely on extracting complex features. It is not limited to transformation param- eters but also includes code transformations. We develop a random code generator to generate the training data and release the generator publicly. We evaluated the proposed model and show that it had a low error rate of 16% MAPE. We integrate this model in a search space method and show that the integrated approach enables TIRAMISU to auto- matically find sequences of code transformations that are competitive with state of the art compilers. A Deep Learning Based Cost Model for Automatic Code Optimization REFERENCES Adams, A., Ma, K., Anderson, L., Baghdadi, R., Li, T.- M., Gharbi, M., Steiner, B., Johnson, S., Fatahalian, K., Durand, F., and Ragan-Kelley, J. Learning to optimize halide with tree search and random programs. ACM Trans. Graph., 38(4):121:1–121:12, July 2019. ISSN 0730-0301. doi: 10.1145/3306346.3322967. URL http: //doi.acm.org/10.1145/3306346.3322967. Bachir, M., Brault, F., Gregg, D., Cohen, A., et al. Minimal unroll factor for code generation of software pipelining. International Journal of Parallel Programming, 41(1): 1–58, 2013. Baghdadi, R., Cohen, A., Guelton, S., Verdoolaege, S., In- oue, J., Grosser, T., Kouveli, G., Kravets, A., Lokhmotov, A., Nugteren, C., Waters, F., and Donaldson, A. F. PEN- CIL: towards a platform-neutral compute intermediate language for dsls. CoRR, abs/1302.5586, 2013a. URL http://arxiv.org/abs/1302.5586. Baghdadi, R., Cohen, A., Verdoolaege, S., and Trifunovic, K. Improved loop tiling based on the removal of spurious false dependences. TACO, 9(4):52, 2013b. Baghdadi, R., Beaugnon, U., Cohen, A., Grosser, T., Kruse, M., Reddy, C., Verdoolaege, S., Betts, A., Donaldson, A. F., Ketema, J., Absar, J., Haastregt, S. v., Kravets, A., Lokhmotov, A., David, R., and Hajiyev, E. Pencil: A platform-neutral compute intermediate language for accelerator programming. In Proceedings of the 2015 In- ternational Conference on Parallel Architecture and Com- pilation (PACT), PACT ’15, pp. 138–149, Washington, DC, USA, 2015a. IEEE Computer Society. ISBN 978-1- 4673-9524-3. doi: 10.1109/PACT.2015.17. URL http: //dx.doi.org/10.1109/PACT.2015.17. Baghdadi, R., Cohen, A., Grosser, T., Verdoolaege, S., Lokhmotov, A., Absar, J., van Haastregt, S., Kravets, A., and Donaldson, A. F. PENCIL language specifica- tion. Research Rep. RR-8706, INRIA, 2015b. URL https://hal.inria.fr/hal-01154812. Baghdadi, R., Ray, J., Romdhane, M. B., Del Sozzo, E., Akkas, A., Zhang, Y ., Suriana, P., Kamil, S., and Amaras- inghe, S. Tiramisu: A polyhedral compiler for express- ing fast and portable code. In Proceedings of the 2019 IEEE/ACM International Symposium on Code Genera- tion and Optimization, CGO 2019, pp. 193–205, Piscat- away, NJ, USA, 2019. IEEE Press. ISBN 978-1-7281- 1436-1. URL http://dl.acm.org/citation. cfm?id=3314872.3314896. Baghdadi, R., Debbagh, A. N., Abdous, K., Benhamida, F. Z., Renda, A., Frankle, J. E., Carbin, M., and Amaras- inghe, S. Tiramisu: A polyhedral compiler for dense and sparse deep learning, 2020. Bondhugula, U., Hartono, A., Ramanujam, J., and Sadayap- pan, P. A practical automatic polyhedral parallelizer and locality optimizer. In PLDI, pp. 101–113, 2008. Chen, T., Zheng, L., Yan, E., Jiang, Z., Moreau, T., Ceze, L., Guestrin, C., and Krishnamurthy, A. Learning to optimize tensor programs. In Advances in Neural Information Processing Systems, pp. 3389–3400, 2018. Cummins, C., Petoumenos, P., Wang, Z., and Leather, H. End-to-end deep learning of optimization heuristics. In 2017 26th International Conference on Parallel Architec- tures and Compilation Techniques (PACT), pp. 219–232. IEEE, 2017. Feautrier, P. Array expansion. In Proceedings of the 2nd international conference on Supercomputing, pp. 429– 441, St. Malo, France, 1988. ACM. ISBN 0-89791-272-1. doi: 10.1145/55364.55406. URL http://portal. acm.org/citation.cfm?id=55406. Fursin, G., Miranda, C., Temam, O., Namolaru, M., Yom- Tov, E., Zaks, A., Mendelson, B., Bonilla, E., Thomson, J., Leather, H., Williams, C., O’Boyle, M., Barnard, P., Ashton, E., Courtois, E., and Bodin, F. MILEPOST GCC: machine learning based research compiler. In GCC Summit, Ottawa, Canada, June 2008. URL https:// hal.inria.fr/inria-00294704. Glorot, X. and Bengio, Y . Understanding the difficulty of training deep feedforward neural networks. Journal of Machine Learning Research - Proceedings Track, 9: 249–256, 01 2010. Grosser, T., Groslinger, A., and Lengauer, C. Polly - per- forming polyhedral optimizations on a low-level interme- diate representation. Parallel Processing Letters, 22(4), 2012. URL http://dblp.uni-trier.de/db/ journals/ppl/ppl22.html#GrosserGL12. Grosser, T., Cohen, A., Holewinski, J., Sadayappan, P., and Verdoolaege, S. Hybrid hexagonal/classical tiling for gpus. In Proceedings of Annual IEEE/ACM International Symposium on Code Generation and Optimization, CGO ’14, pp. 66:66–66:75, New York, NY , USA, 2014. ACM. Hochreiter, S. and Schmidhuber, J. Long short-term mem- ory. Neural Comput., 9(8):1735–1780, November 1997. ISSN 0899-7667. doi: 10.1162/neco.1997.9.8.1735. URL https://doi.org/10.1162/neco.1997. 9.8.1735. Lefebvre, V . and Feautrier, P. Automatic storage man- agement for parallel programs. Parallel Computing, 24:649–671, 1998. ISSN 01678191. doi: 10.1016/ S0167-8191(98)00029-5. A Deep Learning Based Cost Model for Automatic Code Optimization Loshchilov, I. and Hutter, F. Fixing weight decay regular- ization in adam. CoRR, abs/1711.05101, 2017. URL http://arxiv.org/abs/1711.05101. Louis-Noel, P. PolyBench suite. http://www.cse.ohio- state.edu/˜pouchet/software/polybench/, 2010. URL http://www.cse.ohio-state.edu/ ˜pouchet/software/polybench/. Magni, A., Dubach, C., and O’Boyle, M. Automatic optimization of thread-coarsening for graphics proces- sors. In Proceedings of the 23rd International Confer- ence on Parallel Architectures and Compilation, PACT ’14, pp. 455–466, New York, NY , USA, 2014. Associa- tion for Computing Machinery. ISBN 9781450328098. doi: 10.1145/2628071.2628087. URL https://doi. org/10.1145/2628071.2628087. Mendis, C., Amarasinghe, S. P., and Carbin, M. Ithe- mal: Accurate, portable and fast basic block through- put estimation using deep neural networks. CoRR, abs/1808.07412, 2018. URL http://arxiv.org/ abs/1808.07412. Paszke, A., Gross, S., Massa, F., Lerer, A., Bradbury, J., Chanan, G., Killeen, T., Lin, Z., Gimelshein, N., Antiga, L., Desmaison, A., Kopf, A., Yang, E., DeVito, Z., Rai- son, M., Tejani, A., Chilamkurthy, S., Steiner, B., Fang, L., Bai, J., and Chintala, S. Pytorch: An imperative style, high-performance deep learning library. In Wal- lach, H., Larochelle, H., Beygelzimer, A., d’Alch´e Buc, F., Fox, E., and Garnett, R. (eds.), Advances in Neural In- formation Processing Systems 32, pp. 8024–8035. Curran Associates, Inc., 2019. Paul, F. and Christian, L. The polyhedron model. In Padua, D. (ed.), Encyclopedia of Parallel Computing, pp. 1581, 1592. Springer, 2011. Quiller´e, F. and Rajopadhye, S. Optimizing memory us- age in the polyhedral model. ACM Trans. on Program- ming Languages and Systems, 22(5):773–815, September 2000. Ragan-Kelley, J., Adams, A., Paris, S., Levoy, M., Ama- rasinghe, S., and Durand, F. Decoupling algorithms from schedules for easy optimization of image processing pipelines. ACM Trans. Graph., 31(4):32:1–32:12, July 2012. ISSN 0730-0301. Rahman, M., Pouchet, L.-N., and Sadayappan, P. Neural network assisted tile size selection. InInternational Work- shop on Automatic Performance Tuning (IWAPT’2010). Berkeley, CA: Springer Verlag, 2010. Smith, L. N. and Topin, N. Super-convergence: Very fast training of residual networks using large learning rates. CoRR, abs/1708.07120, 2017. URL http://arxiv. org/abs/1708.07120. Trifunovic, K., Nuzman, D., Cohen, A., Zaks, A., and Rosen, I. Polyhedral-model guided loop-nest auto- vectorization. In 2009 18th International Conference on Parallel Architectures and Compilation Techniques, pp. 327–337, 2009. Trifunovic, K., Cohen, A., Edelsohn, D., Li, F., Grosser, T., Jagasia, H., Ladelsky, R., Pop, S., Sjodin, J., and Upadrasta, R. GRAPHITE two years after: First lessons learned from Real-World polyhedral compilation, January 2010. Vasilache, N., Zinenko, O., Theodoridis, T., Goyal, P., De- Vito, Z., Moses, W. S., Verdoolaege, S., Adams, A., and Cohen, A. Tensor comprehensions: Framework-agnostic high-performance machine learning abstractions. CoRR, abs/1802.04730, 2018. Wolf, M. E. and Lam, M. S. A loop transformation theory and an algorithm to maximize parallelism. IEEE transac- tions on parallel and distributed systems, 2(4):452–471, 1991. Yang, Z., Dai, Z., Yang, Y ., Carbonell, J. G., Salakhut- dinov, R., and Le, Q. V . Xlnet: Generalized autore- gressive pretraining for language understanding. CoRR, abs/1906.08237, 2019. URL http://arxiv.org/ abs/1906.08237. A Deep Learning Based Cost Model for Automatic Code Optimization A A PPENDIX A.1 Model Architecture Details and Training Methodology The computation embedding layer is a fully connected mul- tilayer perceptron (MLP), feedforward neural network that takes 1235-dimensional computation vectors and generates 180-dimensional embeddings. We use 3 intermediate lay- ers of 600, 350, 200 neurons respectively. The output of each layer is transformed by the ELU function and fed to a dropout layer with a dropout probability of 0.225, and then passed to the next layer. This succession of the activation function and the dropout layer is applied to all the neural networks of this model. The two LSTM cells in the loop embedding unit have identical input and hidden vector sizes that correspond to the output of the computation embedding layer (180). The feedforward neural network that maps the concatenated hidden vectors to 180-dimensional loop embedding have one intermediate layer of size 200. The regression layer that maps the program embeddingvector to a speedup value, has two intermediate layers with 200 and 180 neurons. We implemented our model in PyTorch (Paszke et al., 2019) (0.4.1.post2). All model parameters are learnable from the computation embedding layer to the regression layer by way of the recursive loop embedding layer. For the loss function, we used MAPE, a normalized metric based on L1. This loss function is suitable for speedup prediction because the target value is positive by design. In addition, the function motivates the model to be equitably accurate in the wide range of speedups we have. The Glorot initialization (Glorot & Bengio, 2010) is adopted for all weights of the model. We train our model using AdamW (Loshchilov & Hutter, 2017) with a weight decay coefficient of 0.0075. The learning rate is scheduled by the One Cycle Policy (Smith & Topin, 2017) with a maximum learning rate of 0.001. The other optimizer parameters are left on their default values. The best accuracy is achieved after about 700 epochs of training. The training set is processed in batches of 32 data points. Each batch is formed by code transformations belonging to the same algorithm. The rationale for this grouping is that it is faster to operate on data points having the same tree structure. A.2 Benchmark Sizes and Parameters Table 3 summarizes the benchmarks’ input sizes and param- eters used in Section 6. A.3 More Detailed Evaluation Figure 8 gives an overview of the correlation between the predicted and measured speedups over 16 programs ran- domly selected from the test set. Each chart represents the Benchmark Input size and parameters box blur 3 × 1024 × 1024 conv + relu batch size: 8 input size: 1024 × 1024 × 3 kernel size: 3 × 3 output features: 2 convolution batch size: 8 input size: 1024 × 1024 × 3 kernel size: 3 × 3 output features: 2 cvtcolor 3 × 1024 × 1024 doitgen 256 × 256 × 128, 256 × 256 heat2d 1024 × 1024 heat3d 770 × 898 × 1024 jacobi2d 130 × 1024 mvt 1024 × 1024 seidel2d 256 × 256 Table 3: Benchmarks input sizes and parameters 10 50 5 1 0.5 0.1 0.05 0.001 10 50 5 1 0.5 0.1 0.05 0.001 10 50 5 1 0.5 0.1 0.05 0.001 10 50 5 1 0.5 0.1 0.05 0.001 10 50 5 1 0.5 0.1 0.05 0.001 10 50 5 1 0.5 0.1 0.05 0.001 10 50 5 1 0.5 0.1 0.05 0.001 10 50 5 1 0.5 0.1 0.05 0.001 Measured speedups Predicted speedups Figure 8: Measured vs predicted speedup on 16 random programs from the test set, each blue dot represents a code transformation with respect to its measured speedup and its predicted speedup. 32 random transformations applied on each program with blue dots, the closer a blue dot is to the red line the lower the prediction error is. This figure shows that the cost model’s predictions fit well the distribution and the range of the speedups and does not just predict an average value for each program. Evaluating Heuristic Optimization Phase Order Search Algorithms Prasad A. Kulkarni, David B. Whalley, Gary S. Tyson Florida State University Computer Science Department Tallahassee, FL 32306-4530 fkulkarni,whalley,tysong@cs.fsu.edu Jack W. Davidson University of Virginia Department of Computer Science Charlottesville, VA 22904-4740 jwd@virginia.edu Abstract Program-specic or function-specic optimization phase sequences are universally accepted to achieve better over- all performance than any xed optimization phase order- ing. A number of heuristic phase order space search algo- rithms have been devised to nd customized phase order- ings achieving high performance for each function. How- ever, to make this approach of iterative compilation more widely accepted and deployed in mainstream compilers, it is essential to modify existing algorithms, or develop new ones that nd near-optimal solutions quickly. As a step in this direction, in this paper we attempt to identify and un- derstand the important properties of some commonly em- ployed heuristic search methods by using information col- lected during an exhaustive exploration of the phase order search space. We compare the performance obtained by each algorithm with all others, as well as with the optimal phase ordering performance. Finally, we show how we can use the features of the phase order space to improve exist- ing algorithms as well as devise new, and better performing search algorithms. 1. Introduction Current compilers contain numerous different optimiza- tion phases. Each optimization phase analyzes the program and attempts to change the code in some way to produce a semantically equivalent program that performs better for one or some combination of constraints, such as speed, code size and power. Most optimization phases share re- sources (such as registers), and require certain conditions in the code to be applicable before applying a transformation. Each optimization phase may consume or release resources, as well as create or destroy specic conditions. As a result, phases interact with each other, by generating or remov- ing opportunities for application of other phases. In many performance-oriented application domains it is important to nd the best order of applying optimization phases so that very high-quality code can be produced. This problem of nding the best sequence of optimization phases to apply is known as the phase ordering problem in compilers. The space of all possible orderings of optimization phases is huge since most current compilers contain nu- merous different optimization phases with few restrictions imposed on the order of applying these phases. Prior re- search has found that no single ordering of phases can achieve optimal performance on all applications or func- tions [1, 2, 3, 4, 5, 6]. The phase ordering problem is difcult since even after decades of research the relation- ships and interactions between optimization phases remain ill-understood. The only consensus is that the phase re- lationships change with the function being optimized, the manner in which optimizations are implemented in the com- piler, and the characteristics of the target architecture. Due to such factors, iterative compilers that evaluate numerous different orderings of optimization phases have found wide appeal to search for the best phase order as well as phase parameters on a per-function basis. Exhaustive exploration of the optimization phase order space, although possible in a reasonable amount of time for a large majority of the functions [7, 8], takes prohibitively long for most large functions to make it suitable for use in typical iterative compilers. Instead, faster heuristic algo- rithms that scan only a portion of the phase order space are more commonly employed. However, such methods do not evaluate the entire space to provide any guarantees about the quality of the solutions obtained. Commonly used heuristic algorithms to address the phase ordering problem include genetic algorithms [3, 4], hill climbing algorithms [9, 10], as well as random searches of the space [11]. In this paper we evaluate many different heuristic search approaches to determine the important characteristics of each algorithm as related to the phase order space. We also evaluate their performance, comparing the performance with other heuristic approaches as well as with optimal or- derings. We are able to perform a very thorough study since we have completely enumerated the phase order spaces of our compiler for hundreds of functions and can sim- ply lookup information instead of compiling and simulating each ordering of phases. Thus, the main contributions of this paper are: 1. This study is the most detailed evaluation of the perfor- mance and cost of different heuristic search methods, and the rst to compare their performance with the op- timal phase ordering. 2. We isolate and evaluate several properties of each stud- ied heuristic algorithm, and demonstrate the signi- cance and difculty in selecting the correct optimiza- tion phase sequence length, which is often ignored or kept constant in most previous studies on optimization phase ordering. 3. This study identies and illustrates the importance of leaf function instances, and shows how we can exploit the properties of leaf instances to enhance existing al- gorithms as well as to construct new search algorithms. The paper is organized as follows. In the next section we will discuss research related to the current work. Our experimental setup will be described in Section 3. In Sec- tion 4 we will describe the results of our study to determine the properties of the phase order search space and evaluate various heuristic search algorithms. Finally, we will present our conclusions in Section 5. 2. Related Work Optimization phase ordering has been a long standing and important issue in compiler optimizations, and as such has received much recent attention from researchers. Sev- eral researchers have attempted to formally specify com- piler optimizations in order to systematically address the phase ordering problem. Whiteld and Soffa developed a framework based on axiomatic specications of optimiza- tions [2, 12]. This framework was employed to list the potential enabling and disabling interactions between op- timizations, which were then used to derive an application order for the optimizations. The main drawback was that in cases of cyclic interactions between two optimizations, it was not possible to determine a good ordering automatically without detailed information about the compiler. Follow-up work on the same topic has seen the use of additional an- alytical models, including code context and resource (such as cache) models, to determine and predict other proper- ties of optimization phases such as the impact of optimiza- tions [13], and the protability of optimizations [14]. Some other work has proposed a Unied Transformation Frame- work (UTF) to provide a uniform and systematic represen- tation of iteration reordering transformations and their arbi- trary combinations [15]. It is possible using UTF to trans- form the optimization phase order space into a polyhedral space, which is considered by some researchers to be more convenient for a systematic exploration than the original space [16]. However, this work is restricted to loop opti- mizations, and needs to be extended to other optimizations before it could be adopted in typical iterative compilers. Earlier work in iterative compilation concentrated on nding good parameter settings for a few optimizations, such as loop unrolling and loop tiling [10, 17, 6]. In cases where exhaustive exploration was expensive, researchers used heuristic algorithms, such as grid-based searches, hill climbers, and genetic algorithms, to scan only a portion of the search space. A common deduction is that typical pro- gram search spaces, on a variety of different architectures, generally contain enough local minima that biased sampling techniques should nd good solutions. Iterative compila- tion usually comes at the cost of a large number of program executions. In order to reduce the cost, some studies have looked at incorporating static architectural models, particu- larly cache models, into their approach [18]. Research on the phase ordering problem over all or most of the optimization phases in a compiler has typically con- centrated on nding effective (rather than optimal) phase sequences by evaluating only a portion of the phase order search space. A method, called Optimization-Space Ex- ploration [5], uses static performance estimators to reduce the search time. In order to prune the search they limit the number of congurations of optimization-parameter value pairs to those that are likely to contribute to performance improvements. This area has also seen the application of other search techniques to intelligently search the optimiza- tion space. Hill climbers [9] and genetic algorithms [3, 4] have been employed during iterative algorithms to nd opti- mization phase sequences better than the default one used in their compilers. Such techniques are often combined with aggressive pruning of the search space [19, 20] to make searches for effective optimization phase sequences faster and more efcient. Successful attempts have also been made to use predictive modeling and code context informa- tion to focus search on the most fruitful areas of the phase order space for the program being compiled [11]. Other ap- proaches to reduce compilation time estimate the number of instructions executed and use that as a means to prune the number of versions of a program that need to be executed or simulated for evaluation [21, 8]. Researchers have also attempted a near-optimal reso- lution of the phase ordering problem considering all the phases present in their compilers. Kulkarni et al. demon- strated that for typical optimization phases applied in a compiler backend it is possible to exhaustively evaluate the phase order space for most of the functions in several em- bedded benchmarks [7, 8]. This was made possible by using techniques to drastically prune the space of distinct func- tion instances, as well as reducing the number of program executions to estimate the performances of all nodes in the space. However, they were unable to exhaustively explore the space for some of the largest functions, while some other large functions each took several days to evaluate. This shows that exhaustive space evaluation may still be infea- sible for routine use in typical iterative compilers. In spite of the wide-spread use of heuristic approaches, there have been few attempts to evaluate and compare their properties and performance in the context of the characteris- tics of the phase order space. Kisuki et al. analyzed the per- formance of ve different search algorithms, and reported the observation that heuristic algorithms do not differ much in their efciency [10]. However, this study was performed on a space of only two optimizations (with different param- eters), and did not take in to account properties of the phase order space. A more detailed evaluation was performed by Almagor et al. [9], which attempted to relate features of the phase order space with the efciency and performance of different heuristic algorithms. This study was, however, in- complete since they had restricted their sequence length to be of a xed size. This earlier work also did not have ac- cess to the entire phase order space features, and lacked a knowledge of the optimal phase order performance. 3. Experimental Framework In this section we rst describe the compiler framework, and then explain our experimental setup. 3.1. Compiler Framework The research in this paper uses the Very Portable Opti- mizer (VPO) [22], which is a compiler back end that per- forms all its optimizations on a single low-level interme- diate representation called RTLs (Register Transfer Lists). Since VPO uses a single representation, it can apply most analysis and optimization phases repeatedly and in an arbi- trary order. VPO compiles and optimizes one function at a time. This is important since different functions may have very different best orderings, so any strategy that requires all functions in a le to have the same phase order will al- most certainly not be optimal. At the same time, restrict- ing the phase ordering problem to a single function helps to make the phase order space more manageable. The com- piler has been targeted to generate code for the StrongARM SA-100 processor using Linux as its operating system. We used the SimpleScalar set of functional simulators [23] for the ARM to get dynamic performance measures. Table 1 describes each of the 15 candidate code- improving phases that were used during the exhaustive ex- ploration of the optimization phase order search space. In addition, register assignment, which is a compulsory phase that assigns pseudo registers to hardware registers, must be performed. VPO implicitly performs register assignment before the rst code-improving phase in a sequence that re- quires it. After applying the last code-improving phase in a sequence, VPO performs another compulsory phase that inserts instructions at the entry and exit of the function to manage the activation record on the run-time stack. Fi- nally, the compiler also performs predication and instruc- tion scheduling before the nal assembly code is produced. These last two optimizations should only be performed late in the compilation process in the VPO compiler, and so are not included in the set of re-orderable optimization phases. For the experiments described in this paper we used a subset of the benchmarks from the MiBench benchmark suite, which are C applications targeting specic areas of the embedded market [24]. We selected two benchmarks from each of the six categories of applications present in MiBench. Table 2 contains descriptions of these programs. VPO compiles and optimizes individual functions at a time. The 12 benchmarks selected contained a total of 244 func- tions, out of which 88 were executed (at least once) with the input data provided with each benchmark. 3.2. Experimental Setup For this study we exhaustively enumerate the phase or- der space for a large number of functions. This enumer- ation enables us to accurately investigate the properties of the search space, to study heuristic search algorithms, to tune the algorithms, to suggest new algorithms, as well as to compare the efciency of different heuristic algorithms in nding optimal phase ordering for each function. In this section we will describe our setup for the current research. We use the algorithm proposed by Kulkarni et al. [7, 8] to exhaustively evaluate the phase order space for the func- tions in our benchmark suite. The algorithm is illustrated in Figure 1. The phase ordering problem is viewed as an eval- uation of all possible distinct function instances that can be generated by changing the order of optimization phases in a compiler. This approach to the phase ordering problem makes no assumptions about the phase sequence length for each function, and allows phases to be repeated as many times as they can possibly be active in the same sequence. Thus, the phase ordering space is complete in each case. However, it is important to note that a different compiler, with a different or greater set of optimization phases can possibly generate better code than the optimal instance pro- duced by VPO. Thus, optimal in the context of this work refers to the best code that can be produced by any opti- mization phase ordering in VPO and is not meant to imply a universally optimum solution. The algorithm can be briey summarized as follows: Optimization Phase Gene Description branch chaining b Replaces a branch or jump target with the target of the last jump in the jump chain. common subexpression elimination c Performs global analysis to eliminate fully redundant calculations, which also includes global constant and copy propagation. remove unreach. code d Removes basic blocks that cannot be reached from the function entry block. loop unrolling g To potentially reduce the number of comparisons and branches at runtime and to aid scheduling at the cost of code size increase. dead assign. elim. h Uses global analysis to remove assignments when the assigned value is never used. block reordering i Removes a jump by reordering blocks when the target of the jump has only a single predecessor. minimize loop jumps j Removes a jump associated with a loop by duplicating a portion of the loop. register allocation k Uses graph coloring to replace references to a variable within a live range with a register. loop transformations l Performs loop-invariant code motion, recurrence elimination, loop strength reduction, and in- duction variable elimination on each loop ordered by loop nesting level. code abstraction n Performs cross-jumping and code-hoisting to move identical instructions from basic blocks to their common predecessor or successor. eval. order determ. o Reorders instructions within a single basic block in an attempt to use fewer registers. strength reduction q Replaces an expensive instruction with one or more cheaper ones. For this version of the com- piler, this means changing a multiply by a constant into a series of shift, adds, and subtracts. reverse branches r Removes an unconditional jump by reversing a cond. branch when it branches over the jump. instruction selection s Combines pairs or triples of instructions together where the instructions are linked by set/use dependencies. Also performs constant folding and checks if the resulting effect is a legal in- struction before committing to the transformation. remove useless jumps u Removes jumps and branches whose target is the following positional block. Table 1. Candidate Optimization Phases along with Their Designations 1. The algorithm starts with the un-optimized function instance. A depth-rst search algorithm is used to produce the next sequence to evaluate. Each new se- quence appends one phase to a previous sequence re- sulting in a new function instance, in depth rst order. 2. Phases not successful in changing the program repre- sentation do not need further evaluation. 3. The next stage uses CRC hash values [25], calculated on the entire function, to compare the current function instance with all previous distinct function instances. If the current function instance is identical to an in- stance previously produced by some other phase se- quence, then only one needs to be evaluated, and so the current instance is discarded. 4. Even if two function instances are not identical, it is possible that the only differences may lie in the reg- ister numbers being used, or the labels assigned to the various basic blocks. In such cases the two function in- stances will still perform identically, and so the current function instance no longer needs further evaluation. 5. The next step determines the performance of each dis- tinct function instance. In order to reduce the num- ber of program simulations, the algorithm only simu- lates one function instance from the set of function in- stances having the same basic block control ow. The rst function instance with a new block control ow is instrumented and simulated to obtain the number of times each block is executed. The dynamic frequency measure for the each function instance is determined by multiplying the block execution counts by the esti- mated number of static cycles for each block. These dynamic frequency measures have been shown to bear a strong correlation with simulated cycles. Category Program Description auto bitcount test proc. bit manipulation abilities qsort sort strings using the quicksort algo. network dijkstra Dijkstra's shortest path algorithm patricia construct patricia trie for IP trafc telecomm fft fast fourier transform adpcm compress 16-bit linear PCM samples to 4-bit samples consumer jpeg image compression and decomp. tiff2bw convert color tiff image to b&w image security sha secure hash algorithm blowsh symmetric block cipher with variable length key ofce search searches for given words in phrases ispell fast spelling checker Table 2. MiBench Benchmarks Used The exhaustive enumeration of any function is stopped if the time required exceeds an approximate limit of two calculate function performance generate next optimization sequence using depth-first approach last phase active? Y Nidentical function instance? equivalent N instance? function control-flow structure? seenN Y N Y Y simulate application Figure 1. Steps During an Exhaustive Evaluation of the Phase Order Space for Each Function weeks. Using the above algorithm and cut-off criteria we were able to enumerate completely the optimization phase order space for 234 out the 244 functions that we studied. Out of the 88 executed functions, we were able to com- pletely enumerate 79. We represent the phase order space for every function in the form of a DAG (Directed Acyclic Graph), as shown in Figure 2. Nodes in the DAG represent distinct function instances and edges represent transitions from one node to the next on application of an optimization phase. The DAG then enables much faster evaluation of any search heuristic, since compilation as well as execution can be replaced with a simple table lookup in the DAG to deter- mine the performance of each phase ordering. As a result, the study of the various algorithms is fast, and it is possible to evaluate various parameters of the algorithms as well as the search space. b c a d d a d 3 4 (b) Depth-first Traversal 6 7 8 1 52 a c Figure 2. Directed Acyclic Graph Represent- ing the Phase Order Space of a Function 4 Study of Common Heuristic Search Tech- niques Over the past decades researchers have employed vari- ous heuristic algorithms to cheaply nd effective solutions to the phase ordering problem. However, several issues re- garding the relative performance and cost of each algorithm, as well as the effect of changing different algorithm param- eters on that algorithm's performance are as yet uncertain and not clearly understood. In this section we will perform a thorough evaluation and comparison of commonly used heuristic methods. Based on the phase order space charac- teristics we will also develop new techniques and suggest several improvements to existing algorithms. 4.1. Local Search Techniques Local search techniques, such as hill climbing and sim- ulated annealing, can only migrate to neighboring points from one iteration to the next during their search for good solutions. Central to these algorithms is the denition of neighbors of any point in the space. For this study, we de- ne the neighbors of a sequence to be all those sequences that differ from the base sequence in only one position. Thus, for a compiler with only three optimization phases a, b and c, the sequence shown in the rst column of Table 3 will have the sequences listed in the following columns as its neighbors. The position that differs in each neighbor is indicated in bold. For a compiler with m optimization phases, a sequence of length n will have (m 1)n neigh- bors. Unless the search space is extremely smooth, these local search algorithms have a tendency to get stuck in a local minimum, which are points that are not globally mini- mum, but have better tness values than any of their neigh- bors. For a comprehensive study of these algorithms it is important to rst understand relevant properties of the opti- mization phase order space. The results from this study are presented in the next section. bseq neighbors a b c a a a a a a b b b a c b b b b c c c c c a b c c a a a a a a a b c Table 3. Neighbors in Heuristic Searches 4.1.1 Distribution of Local Minima in the Phase Order Space Earlier studies have attempted to probe the properties of the phase order space [17, 9]. Such studies, however, only looked at a small portion of the space, and ignored im- portant factors affecting the nature and distribution of lo- cal minima in phase order spaces. One such factor, com- monly ignored, is the optimization sequence length. It is almost impossible to estimate the best sequence length to use due to the ability and tendency of optimization phases to enable other phases. During our experiments, maximum sequence lengths of active phases varied from 3 to 44 over different functions, with considerable variation within the same function itself for different phase orderings. The goal of analyzing the search space, in the context of local search techniques, is to nd the properties and distribution of all local minima in each phase order search space. However, there are some difcult hurdles in achieving this goal: Variable sequence length: Since the best sequence length for each function is unknown, an ideal analysis would require nding the properties of local minima for all possible sequence lengths. This requirement is needed be- cause any sequence of attempted phases of any length de- nes a point in the search space DAG. Conversely, a sin- gle point in the space can be dened by, potentially, innite number of attempted sequences of different lengths. This is important, since different sequences dening the same point will have different neighbors. This implies that some of those sequences may be locally optimum, while others may be not, even though they dene the same point in the phase order space. For example, the attempted sequences fb ! ag, fc ! b ! ag, and fd ! b ! c ! ag all dene the same node 4 in the DAG in Figure 2 (Note that, the phases a and b, indicated in bold, are active, while c and d are dormant). Thus, we can see that it is possible to have sequences of different lengths pointing to the same node. Thus, this ideal goal of nding the local minima for all pos- sible sequence lengths is clearly impossible to achieve. Fixed sequence length: A conceptually simpler ap- proach would be to use some oracle to give us the best sequence length to use for each function, and then only an- alyze the space for this single sequence length. The mini- mum reasonable length to use, so that all nodes in the DAG can be reached, would be the maximum active sequence length for each function. For an average maximum active sequence length of 16, over all 234 enumerated functions, we would need to evaluate 1516 different phase orderings for each function. Evaluation of any phase ordering to de- termine if that ordering is a local optimum would in turn re- quire us to lookup the performance of that ordering as well as that of its 15  16 neighbors. This, also, is clearly a huge undertaking considering that the maximum active sequence length we encountered during our exhaustive phase order enumeration study was 44. Due to such issues, in our present experiments, we de- cided to use sampling to probe only a reasonable portion of the phase order search space for some number of different sequence lengths for each function. We use 16 different se- quence lengths. The initial length is set to the length of the sequence of active phases applied by the conventional VPO compiler in batch mode. The remaining sequence lengths are successive increments of one-fourth of the initial se- quence length used for each function. The larger sequence lengths may be needed to accommodate phases which may be dormant at the point they are attempted. For each set of experiments for each function, we rst randomly generate a sequence of the specied length. We then compare the performance of the node that this sequence denes with the performance of all of its neighbors to nd if this sequence is a local optimal. This base node is marked as done. All later sequences are constrained to dene different nodes in the space. As this sampling process progresses it will require an increasing number of attempts to nd a sequence corre- sponding to an unevaluated node in the search space. The process terminates when the average number of attempts to generate a sequence dening a new node exceeds 100. Figures 3(a) and 3(b) illustrate the average phase order space properties over all the executed functions that we studied. The plot labeled % nodes touched in the DAG from Figure 3(a) shows the percentage of nodes that were evalu- ated for local minimum from amongst all nodes in the space DAG. This number initially increases, reaches a peak, and then drops off. This graph, in effect, shows the nature of typical phase order spaces. Optimization phase order space DAGs typically start out with a small width, reach a max- imum around the center of the DAG, and again taper off towards the leaf nodes as more and more function instances generated are detected to be redundant. Smaller attempted sequence lengths in Figure 3(a) dene points higher up in the DAG, with the nodes dened dropping down in the DAG as the length is increased. The next plot labeled avg local minima % distance from optimal in Figure 3(a) measures the average difference in performance from optimal over all the samples at each length. As the sequence lengths in- creased the average performance of the samples gets closer and closer to optimal, until after a certain point the perfor- mance remains more or less constant. This is expected, and can be explained from the last plot in Figure 3(a), la- beled %(avg.active seq. length / batch seq. length), which shows the percentage increase in the average length of ac- tive phases as the attempted sequence length is increased. The ability to apply more active phases implies that the function is better optimized, and thus we see a correspond- ing increase in performance and a smaller percentage of ac- tive phases. The rst plot in Figure 3(b) shows the ratio of sequences reaching local minima to the total sequences probed. This ratio seems to remain more or less constant for different lengths. The small percentage of local minima in the to- tal samples indicates that there are not many local minima (a) Local Minima Information (b) Global Minima Information Figure 3. Search Space Properties in the space. The next plot, %(num global minima / to- tal minima), in this gure shows that the percentage of lo- cally minimum nodes achieving global minima grows with increase in sequence length. This increase is more pro- nounced initially, but subsequently becomes steadier. In the steady state around 45% of local minima display globally optimum performance. This characteristic means that for longer sequence lengths there is a good chance that the lo- cal minimum found during local search algorithms will have globally optimal performance. The nal plot in Figure 3(b), %(functions for which at least one sample reached optimal), presents the percentage of functions for which the probe is able to nd optimal in at least one of its samples. This num- ber shows a similar characteristic of continuously increas- ing with sequence lengths, until it reaches a steady state at close to 100% for larger sequence lengths. Hence, for small multiples of the batch sequence length the local search al- gorithms should be able to nd global minima with a high probability for most of the functions. Thus, this study illustrates that it is important to nd the correct balance between increase in sequence length, per- formance obtained, and the time required for the search. Al- though larger sequence lengths tend to perform better they are also more expensive to evaluate, since they have more neighbors, and evaluation of each neighbor takes longer. It is worthwhile to note that we do not need to increase the se- quence lengths indenitely. After a modest increase in the sequence lengths, as compared to the xed batch sequence length, we are able to obtain most of the potential benets of any further increases in sequence lengths. 4.1.2 Hill Climbing In this section we evaluate the performance of the steepest descent hill climbing heuristic algorithm for different se- quence lengths [9]. The algorithm is initiated by randomly populating a phase sequence of the specied length. The performance of this sequence is evaluated, along with that of all its neighbors. If the best performing neighbor has equal or better performance than the base sequence, then that neighbor is selected as the new base sequence. This process is repeated until a local optimum is reached, i.e., the base sequence performs better than all of its neighbors. For each sequence length, 100 iterations of this algorithm are performed by selecting random starting points in the search space. The sequence lengths were incremented 40 times starting from the length of the active batch sequence, with each increment equal to one-fourth the batch length. Figures 4(a) and 4(b) illustrate the results of the hill climbing experiments. The plot marked % best perf. dis- tance from optimal in Figure 4(a) compares the best solution found by the hill climbing algorithm with optimal, averaged over the 79 executed functions, and over all 100 iterations for each sequence length. We can see that even for small sequence lengths the algorithm is able to obtain a phase or- dering whose best performance is very close to optimal. For lengths greater than 1.5 times the batch sequence length, the algorithm is able to reach optimal in most cases. The plot avg. steps to local minimum in Figure 4(a) shows that the simple hill climbing algorithm requires very few steps to reach local optimal, and that the average distance to the local optimal decreases with increase in sequence lengths. This decrease in the number of steps is caused by better performance delivered by each typical sequence when the initial sequence length is increased, so that in effect the al- gorithm starts out with a better initial sequence, and takes fewer steps to the local minimum. As mentioned earlier, the hill climbing algorithm is iter- ated 100 times for each sequence length and each function to eliminate the noise caused by the random component of the algorithm. The rst plot in Figure 4(b), avg. % iter- ations reaching optimal, illustrates that the average num- ber of iterations reaching optimal increases with increase in the sequence length up to a certain limit, after which it re- mains more or less constant. A related measure % avg. perf. (a) Local Minima Information (b) Global Minima Information Figure 4. Properties of the Hill Climbing Algorithm distance from optimal, shown in the second plot in Figure 4(b), is the average function performance over all the itera- tions for each sequence length. This measure also shows a marked improvement as the sequence length increases un- til the average performance peaks at around 4% worse than optimal. These results indicate the signicance of select- ing a correct sequence length during the algorithm. Larger sequence lengths lead to larger active sequences that result in the initial performance improvement, but increasing the length incessantly gives diminishing returns while making the algorithm more expensive. 4.1.3 Simulated Annealing Simulated annealing can be dened as a technique to nd a good solution to an optimization problem by trying random variations of the current solution. A worse variation is ac- cepted as the new solution with a probability that decreases as the computation proceeds. The slower the cooling sched- ule, or rate of decrease, the more likely the algorithm is to nd an optimal or near-optimal solution [26]. In our im- plementation, the algorithm proceeds similarly to the hill climbing algorithm by starting from a random initialization point in the phase order space. The sequence length is xed for each run of the algorithm. During each iteration the per- formance of the base sequence is evaluated along with that of all its neighbors. Similar to the hill climbing method, if the performance of the best performing neighbor is better than the performance of the base sequence, then that neigh- bor is selected as the base sequence for the next iteration. However, if the current iteration is not able to nd a neigh- bor performing better than the base sequence, the algorithm can still migrate to the best neighbor based on its current temperature. The worse solution is generally accepted with a probability based on the Boltzmann probability distribu- tion: prob = exp(f T ) (1) where, f is the difference in performance between the cur- rent base sequence and the best neighbor, and T is the cur- rent temperature. Thus, smaller the degradation and higher the temperature the greater the probability of a worse solu- tion being accepted. An important component of the simulated annealing al- gorithm is the annealing schedule, which determines the initial temperature and how it is lowered from high to low values. The assignment of a good schedule generally re- quires physical insight and/or trial and error experiments. In this paper, we attempt to study the effect of different anneal- ing schedules on the performance of a simulated annealing algorithm. For this study, the sequence length is xed at 1.5 times the batch compiler length of active phases. As seen in the hill climbing experiments, this is the smallest sequence length at which the average performance reaches a steady state that is very close to optimal. We conducted a total of 400 experimental runs by varying the initial tem- perature and the annealing schedule. The temperature was varied from 0 to 0.95 in steps of 0.5. For each temperature we dened 20 different annealing schedules, which control the temperature in steps from 0.5 to 0.95 per iteration. The results for each conguration are averaged over 100 runs to account for noise caused by random initializations. Our results, shown in Figure 5, indicate that for the phase ordering problem, as seen by our compiler, the initial tem- perature as well as the annealing schedule do not have a signicant impact on the performance delivered by the sim- ulated annealing algorithm. The best performance obtained over all the 400 experimental runs is, on average, 0.15% off from optimal, with a standard deviation of 0.13%. Like- wise, other measures obtained during our experiments are also consistent across all 400 runs. The average number of iterations achieving optimal performance during each run is 41.06%, with a standard deviation of 0.81%. The av- erage performance for each run is 15.95% worse than op- timal, with a deviation of 0.55%. However, as expected, the number of steps to a local minimum during each itera- tion for each run increases with increase in the initial tem- perature and the annealing schedule step. As the starting temperature and annealing schedule step are increased, the algorithm accepts more poorly performing solutions before halting. However, this increase in the number of steps to local optimal does not translate into any signicant perfor- mance improvement for our experiments, Figure 5. Increase in the Number of Steps to Local Minimum with Increases in Initial Tem- perature and Annealing Schedule Step 4.2. Greedy Algorithm Greedy algorithms follow the policy of making the lo- cally optimum choice at every step in the hope of nally reaching the global optimum. Such algorithms are com- monly used for addressing several optimization problems with huge search spaces. For the phase ordering problem, we start off with the empty sequence as the base sequence. During each iteration the algorithm creates new sequences by adding each available phase rst to the prex and then as the postx of the base sequence. Each of these sequences is evaluated to nd the best performing sequence in the cur- rent iteration, which is consequently selected as the base se- quence for the next iteration. If there are multiple sequences obtaining the same best performance, then one of these is selected at random. The algorithm is repeated 100 times in order to reduce the noise that can potentially be caused by this random component in the greedy method. Thus, in our case the algorithm has a bounded cost, as it performs a xed number of (15+15=30) evaluations in each step, where 15 is the number of available optimizations in our compiler. Our current implementation of the greedy algorithm is inspired by the approach used by Almagor et al. [9]. Simi- lar to the hill climbing algorithm, the sequence lengths dur- ing the greedy algorithm are varied from the active batch sequence length for each function as the initial length to 11 times the batch length, in increments of one-fourth the batch length. To minimize the effect of the random com- ponent, the algorithm is repeated 100 times for each se- quence length. The best and average performances dur- ing these 100 iterations for each sequence length, averaged over all executed functions, are illustrated in Figure 6. The plots show a similar pattern to the hill climbing perfor- mance graphs. However, it is interesting to note that the best achievable performance during the greedy algorithm is around 1.1% worse than optimal, whereas it is very close to optimal (0.02%) for the hill climbing algorithm. Also, the average performance during the greedy algorithm im- proves more gradually and continues to improve for larger sequence lengths as compared to hill climbing. Figure 6. Greedy Algorithm Performance 4.3. Focusing on Leaf Sequences of Active Phases Leaf function instances are those that cannot be further modied by the application of any additional optimizations phases. These function instances represent leaves in the DAG of the phase order space (e.g. nodes 3, 4, 6, and 8 in Figure 2). Sequences of active phases leading to leaf function instances are called leaf sequences. Working with only the leaf sequences has the advantage that the heuris- tic algorithm no longer needs to guess the most appropriate sequence length to minimize the algorithm running time, while at the same time obtaining the best, or at least close to the best possible performance. Since leaf function in- stances are generated by different lengths of active phase sequences, the length of the leaf sequences is variable. In this section we describe our modications to existing algo- rithms, as well as introduce new algorithms that deal with only leaf sequences. We rst motivate the reason for restricting the heuristic searches to only leaf function instances. Figure 7 shows the distribution of the dynamic frequency counts as com- pared to the optimal for all distinct function instances ob- tained during our exhaustive phase order space evaluation, averaged over all 79 executed functions. From this gure we can see that the performance of the leaf function in- stances is typically very close to the optimal performance, and that leaf instances comprise a signicant portion of op- timal function instances with respect to the dynamic fre- quency counts. This fact is quite intuitive since active op- timizations generally improve performance, and very rarely cause a performance degradation. The main drawback of this approach is that the algorithm will not nd the optimal phase ordering for any function that does not have an opti- mal performing leaf instance. However, we have observed that most functions do contain optimal performing leaf in- stances. For more than 86% of the functions in our bench- mark suite there is at least one leaf function instance that achieved optimal dynamic frequency counts. The average best performance for leaf function instances over all exe- cuted functions is only 0.42% worse than optimal. More- over, leaf function instances comprise only 4.38% of the to- tal space of distinct function instances, which is in turn a mi- nuscule portion of the total phase order search space. Thus, restricting the heuristic search to only the leaf function in- stances constrains the search to only look at a very small portion of the search space that typically consists of good function instances, and increases the probability of nding a near-optimal solution quickly. In the next few sections we will describe some modications to existing algorithms, as well as describe new algorithms that take advantage of the opportunity provided by leaf function instances to nd better performance faster. Figure 7. Average Distribution of Dynamic Frequency Counts 4.3.1 Genetic Algorithm Genetic algorithms are adaptive algorithms based on Dar- win's theory of evolution [27]. These algorithms have been successfully employed by several researchers to address the phase ordering problem and other related issues in compil- ers [4, 3, 28, 29]. Genes correspond to optimization phases and chromosomes correspond to optimization sequences in the genetic algorithm. The set of chromosomes currently under consideration constitutes a population. The number of generations is how many sets of populations are to be evaluated. Our experiments with genetic algorithms sug- gests that minor modications in the conguration of these parameters do not signicantly affect the performance de- livered by the genetic algorithms. For the current study we have xed the number of chromosomes in each population at 20. Chromosomes in the rst generation are randomly initialized. After evaluating the performance of each chro- mosome in the population, they are sorted in decreasing order of performance. During crossover, 20% of chromo- somes from the poorly performing half of the population are replaced by repeatedly selecting two chromosomes from the better half of the population and replacing the lower half of the rst chromosome with the upper half of the second and vice-versa to produce two new chromosomes each time. During mutation we replace a phase with another random phase with a small probability of 5% for chromosomes in the upper half of the population and 10% for the chromo- somes in the lower half. The chromosomes replaced during crossover are not mutated. The only parameter that seems to signicantly affect the performance of the genetic algorithm is the length of each chromosome. We conducted two different studies with ge- netic algorithms. In the rst study we vary the length of the chromosomes (attempted sequence) starting from the batch sequence length to 11 times the batch sequence length, in steps of one-fourth of the batch length. For the second study we modied the genetic algorithm to only work with leaf sequences of active phases. This approach requires maintaining active leaf sequences of different lengths in the same population. After crossover and mutation it is pos- sible that the new sequences no longer correspond to leaf function instances, and may also contain dormant phases. The modied genetic algorithm handles such sequences by rst squeezing out the dormant phases and then extending the sequence, if needed, by additional randomly generated phases to get a leaf sequence. Figures 8(a) and 8(b) shows the performance results, as well as a comparison of the two approaches. Since the modied genetic algorithm for leaf instances does not depend on sequence lengths, the aver- age performance and cost delivered by this new algorithm are illustrated by single horizontal lines in Figures 8(a) and (b).The number of generations is a measure of the cost of the algorithm. Thus, by concentrating on only the leaf func- tion instances, the genetic algorithm is able to obtain close to the best performance at close to the least cost possible for any sequence length. Interestingly, performance of the genetic algorithm for leaf sequences (0.43%) is very close to the best achievable average leaf performance (0.42%). (a) Performance (b) Cost Figure 8. Performance and Cost of Genetic Algorithms (a) Performance (b) Cost Figure 9. Performance and Cost of Random Search Algorithms 4.3.2 Random Search Random sampling of the search space to nd good solutions is an effective technique for search spaces that are typically discrete and sparse, and when the relationships between the various space parameters are not clearly understood. Exam- ples are the search spaces that we are dealing with to address the phase ordering problem. In this study we have attempted to evaluate random sampling, again by performing two dif- ferent sets of experiments similar to the genetic algorithm experiments in the previous section. For the rst set, ran- domly constructed phase sequences of different lengths are evaluated until 100 consecutive sequences fail to show an improvement over the current best. The second set of ex- periments is similar, but only considers leaf sequences or leaf function instances. Figures 9(a) and 9(b) show the performance benets as well as the cost for all our random search experiments. It is interesting to note that random searches are also able to achieve performance close to the optimal for each function in a few number of attempts. Since our algorithm cong- uration mandates the best performance to be held steady for 100 consecutive sequences, we see that the cost of our algorithm is always above 100 attempts. We again notice that leaf sequences consistently obtain good performance for the random search algorithm as well. In fact, for our current conguration, random search algorithm concentrat- ing on only the leaf sequences is able to cheaply outperform the best achievable by any other random search algorithm for any sequence length. 4.3.3 N-Lookahead Algorithm This algorithm scans N levels down the search space DAG from the current location to select the phase that leads to the best subsequence of phases to apply. The critical pa- rameter is the number of levels to scan. For a N lookahead algorithm we have to evaluate 15N different optimization phases to select each phase in the base sequence. This pro- cess can be very expensive, especially for larger values of the lookahead N. Thus, in order for this approach to be feasible we need to study if small values of the lookahead N can achieve near optimal performance for most of the functions. For the current set of experiments we have constrained the values of N to be either 1, 2, or 3 levels of lookahead. Due to the exponential nature of the phase order search space, we believe that any further increase in the lookahead value will make this method too expensive in comparison with other heuristic approaches. Table 4 shows the average performance difference from optimal for the three levels of lookahead over all the executed functions in our set. As expected, the performance improves as the levels of looka- head are increased. However, even after using three lev- els of lookahead the performance is far from optimal. This illustrates the ragged nature of typical phase order search spaces, where it is difcult to predict the nal performance of a phase sequence by only looking at a few number of phases further down from the current location. Lookahead 1 2 3 % Performance 22.90 14.64 5.35 Table 4. Perf. of N-Lookahead Algorithm 5. Conclusions In this paper we studied various properties of the opti- mization phase order space, and evaluated various heuristic search algorithms. Based on our observations regarding the search space properties, we further suggested and evaluated extensions to existing heuristic algorithms, and developed new heuristic methods. This study is also the rst compar- ison of the performance delivered by the different heuris- tic algorithms with the optimal phase ordering. A study of this magnitude would have normally required several man- months to accomplish. However, the presence of the ex- haustive phase order exploration data over a large number of functions meant that this study required no further com- pilation or simulation runs to determine the performance of each unique phase sequence during the heuristic algorithms. We have a number of interesting conclusions from our detailed study: (1) Analysis of the phase order search space indicates that the space is highly discrete and very sparse. (2) The phase order space typically has a few local and global minima. More importantly, the sequence length of attempted phases denes the percentage of local and global minima in the search space. Larger sequence lengths in- crease the probability of nding a global minima, but can also increase the search time to nd a good solution. Thus, it is important to nd the correct sequence lengths to balance algorithm cost, and its ability to reach better performing so- lutions faster. (3) Due to the inherent difculty in determin- ing the ideal sequence length to use during any heuristic method, and the high probability of obtaining near-optimal performance from leaf function instances, we modied ex- isting algorithms to concentrate on only leaf sequences and demonstrated that for many algorithms leaf sequences can deliver performance close to the best, and often times even better than that obtained by excessive increases in sequence lengths for the same algorithms. Moreover, this can be achieved at a fraction of the running cost of the original algorithm since the space of leaf function instances is only 4.38% of the total space of all function instances. (4) On comparing the performance and cost of different heuristic algorithms we nd that simple techniques, such as local hill climbing allowed to run over multiple iterations, can often outperform more complex techniques such as genetic algo- rithms and lookahead schemes. The added complexity of simulated annealing, as compared to hill climbing, is found to not signicantly affect the performance of the algorithm. Random searches and greedy search algorithms achieve de- cent performance, but not as good as the other heuristic ap- proaches for the amount of effort expended. The unpre- dictable nature of phase interactions is responsible for the mediocre performance of the N-lookahead heuristic algo- rithm. (5) Interestingly, most of the heuristic algorithms we evaluated are able to achieve performance close to the best phase ordering performance in acceptable running times for all functions. Thus, in conclusion we nd that differences in performance delivered by different heuristic approaches are not that signicant when compared to the optimal phase ordering performance. Selection of the correct sequence length is important for algorithms that depend on it, but can be safely bypassed without any signicant performance loss wherever possible by concentrating on leaf sequences. 6. Acknowledgments We thank the anonymous reviewers for their constructive comments and suggestions. This research was supported in part by NSF grants EIA-0072043, CCR-0208892, CCR- 0312493, CCF-0444207, CNS-0072043, CNS-0305144, and CNS-0615085. References [1] Steven R. Vegdahl. Phase coupling and constant generation in an optimizing microcode compiler. In Proceedings of the 15th annual workshop on Microprogramming, pages 125– 133. IEEE Press, 1982. [2] D. Whiteld and M. L. Soffa. An approach to ordering opti- mizing transformations. In Proceedings of the second ACM SIGPLAN symposium on Principles & Practice of Parallel Programming, pages 137–146. ACM Press, 1990. [3] Keith D. Cooper, Philip J. Schielke, and Devika Subrama- nian. Optimizing for reduced code space using genetic al- gorithms. In Workshop on Languages, Compilers, and Tools for Embedded Systems, pages 1–9, May 1999. [4] Prasad Kulkarni, Wankang Zhao, Hwashin Moon, Kyungh- wan Cho, David Whalley, Jack Davidson, Mark Bailey, Yun- heung Paek, and Kyle Gallivan. Finding effective optimiza- tion phase sequences. In Proceedings of the 2003 ACM SIG- PLAN conference on Language, Compiler, and Tool for Em- bedded Systems, pages 12–23. ACM Press, 2003. [5] Spyridon Triantafyllis, Manish Vachharajani, Neil Vachhara- jani, and David I. August. Compiler optimization-space ex- ploration. In Proceedings of the international symposium on Code Generation and Optimization, pages 204–215. IEEE Computer Society, 2003. [6] T. Kisuki, P.M.W. Knijnenburg, M.F.P. O'Boyle, F. Bodin, and H.A.G. Wijshoff. A feasibility study in iterative compi- lation. In Proc. ISHPC'99, volume 1615 of Lecture Notes in Computer Science, pages 121–132, 1999. [7] P. Kulkarni, D. Whalley, G. Tyson, and J. Davidson. Exhaus- tive optimization phase order space exploration. In Proceed- ings of the Fourth Annual IEEE/ACM International Sympo- sium on Code Generation and Optimization, March 26-29 2006. [8] Prasad Kulkarni, David Whalley, Gary Tyson, and Jack Davidson. In search of near-optimal optimization phase or- derings. In LCTES '06: Proceedings of the 2006 ACM SIG- PLAN/SIGBED conference on Language, compilers and tool support for embedded systems, pages 83–92, New York, NY, USA, 2006. ACM Press. [9] L. Almagor, Keith D. Cooper, Alexander Grosul, Timothy J. Harvey, Steven W. Reeves, Devika Subramanian, Linda Tor- czon, and Todd Waterman. Finding effective compilation se- quences. In LCTES '04: Proceedings of the 2004 ACM SIG- PLAN/SIGBED conference on Languages, Compilers, and Tools for Embedded Systems, pages 231–239, New York, NY, USA, 2004. ACM Press. [10] T. Kisuki, P. Knijnenburg, , and M.F.P. O'Boyle. Combined selection of tile sizes and unroll factors using iterative com- pilation. In Proc. PACT, pages 237–246, 2000. [11] F. Agakov, E. Bonilla, J. Cavazos, B. Franke, G. Fursin, M. F. P. O'Boyle, J. Thomson, M. Toussaint, and C. K. I. Williams. Using machine learning to focus iterative opti- mization. In Proceedings of the International Symposium on Code Generation and Optimization, pages 295–305, Wash- ington, DC, USA, 2006. IEEE Computer Society. [12] Deborah L. Whiteld and Mary Lou Soffa. An approach for exploring code improving transformations. ACM Trans. Program. Lang. Syst., 19(6):1053–1084, 1997. [13] Min Zhao, Bruce Childers, and Mary Lou Soffa. Predict- ing the impact of optimizations for embedded systems. In LCTES '03: Proceedings of the 2003 ACM SIGPLAN confer- ence on Language, compiler, and tool for embedded systems, pages 1–11, New York, NY, USA, 2003. ACM Press. [14] Min Zhao, Bruce R. Childers, and Mary Lou Soffa. A model- based framework: An approach for prot-driven optimiza- tion. In Proceedings of the international symposium on Code generation and optimization, pages 317–327, Washington, DC, USA, 2005. [15] W. Kelly and W. Pugh. A framework for unifying reordering transformations. Technical Report CS-TR-3193, 1993. [16] Shun Long and Grigori Fursin. A heuristic search algorithm based on unied transformation framework. In 7th workshop on High Performance Scientic and Engineering Computing, Norway, 2005. IEEE Computer Society. [17] F. Bodin, T. Kisuki, P.M.W. Knijnenburg, M.F.P. O'Boyle, and E. Rohou. Iterative compilation in a non-linear opti- misation space. Proc. Workshop on Prole and Feedback Directed Compilation, 1998. [18] P.M.W. Knijnenburg, T. Kisuki, K. Gallivan, and M.F.P. O'Boyle. The effect of cache models on iterative compi- lation for combined tiling and unrolling. In Proc. FDDO-3, pages 31–40, 2000. [19] Prasad Kulkarni, Steve Hines, Jason Hiser, David Whalley, Jack Davidson, and Douglas Jones. Fast searches for effec- tive optimization phase sequences. In Proceedings of the ACM SIGPLAN '04 Conference on Programming Language Design and Implementation, June 2004. [20] Prasad Kulkarni, Steve Hines, David Whalley, Jason Hiser, Jack Davidson, and Douglas Jones. Fast and efcient searches for effective optimization-phase sequences. ACM Trans. Archit. Code Optim., 2(2):165–198, 2005. [21] K. Cooper, A. Grosul, T. Harvey, S. Reeves, D. Subrama- nian, L. Torczon, and T. Waterman. Acme: Adaptive com- pilation made efcient. In Proceedings of the ACM SIG- PLAN/SIGBED Conference on Languages, Compilers, and Tools for Embedded Systems, pages 69–78, June 15-17 2005. [22] M. E. Benitez and J. W. Davidson. A portable global opti- mizer and linker. In Proceedings of the SIGPLAN'88 con- ference on Programming Language Design and Implemen- tation, pages 329–338. ACM Press, 1988. [23] D. Burger and T. Austin. The SimpleScalar tool set, version 2.0. SIGARCH Comput. Archit. News, 25(3):13–25, 1997. [24] Matthew R. Guthaus, Jeffrey S. Ringenberg, Dan Ernst, Todd M. Austin, Trevor Mudge, and Richard B. Brown. MiBench: A free, commercially representative embedded benchmark suite. IEEE 4th Annual Workshop on Workload Characterization, December 2001. [25] W. Peterson and D. Brown. Cyclic codes for error detec- tion. In Proceedings of the IRE, volume 49, pages 228–235, January 1961. [26] Paul E. Black. Simulated annealing. Dictionary of Algo- rithms and Data Structures adopted by the U.S. National Institute of Standards and Technology, December 2004. http://www.nist.gov/dads/HTML/simulatedAnnealing.html. [27] Melanie Mitchell. An Introduction to Genetic Algorithms. Cambridge, Mass. MIT Press, 1996. [28] A. Nisbet. Genetic algorithm optimized parallelization. Workshop on Prole and Feedback Directed Compilation, 1998. [29] Mark Stephenson, Saman Amarasinghe, Martin Martin, and Una-May O'Reilly. Meta optimization: improving compiler heuristics with machine learning. In Proceedings of the ACM SIGPLAN 2003 conference on Programming Language De- sign and Implementation, pages 77–90. ACM Press, 2003. Ansor : Generating High-Performance Tensor Programs for Deep LearningLianmin Zheng, Chenfan Jia, Minmin Sun, Zhao Wu, Cody Hao Yu, Ameer Haj Ali, Yida Wang, Jun Yang, Danyang Zhuo, Koushik Sen, Joseph Gonzalez, Ion Stoica Deep Learning System Stack Introducing Compiler 𝑑𝑒𝑛𝑠𝑒!,#=&$𝑑𝑎𝑡𝑎!,$×𝑤𝑒𝑖𝑔ℎ𝑡#,$𝑟𝑒𝑙𝑢𝑏,𝑜=max(𝑑𝑒𝑛𝑠𝑒!,#,0) A dense layer with ReLU activation•Math expression: •Declaration:dense(o, b) +=data(i, b) * weight(i, o);relu(o, b) =max(dense(o, b), 0.0)Halide dense = compute(shape, lambdab, o: sum(data[b,i] *weight[o,i], i))relu =compute(shape, lambdab, o: max(dense[b,o], 0.0))TVM Billions of possible implementations for it! Related Work on GeneratingHigh-Performance Tensor Programs TVM's Approach ... ManualTemplatefori.0 in range( ):for j.0 inrange( ):for k.0 inrange( ):fori.1 in range( ):for j.1 inrange( ):C[...] +=A[...] * B[...]fori.2 inrange( ):for j.2 inrange( ):D[...] =max(C[...], 0.0) ??????? Parameter SearchAutoTVM: Template-guided searchUse templatesto define the search space for every operator Drawbacks•Not fully-automated -> Requires huge manual effort•Limited search space -> Does not achieve optimal performance TVM: An Automated End-to-End Optimizing Compiler for Deep Learning, OSDI 18 ... IncompleteProgramfori.0 in range(512):for j.0 inrange(512):D[...] =max(C[...], 0.0)How to build the next statement ?Candidate 1Candidate 2Candidate 3Candidate 4 Pruned Pruned KeptKept Beam Search with Early Pruning Learning to Optimize Halide with Tree Search and Random Programs, SIGGRAPH 19 Halide’s Auto-schedulerSequential Construction Based SearchUse beam search to generate the programs sequentiallyDrawbacks•Intermediate candidates are incomplete programs-> The cost model cannot do accurate prediction•Sequential order-> The error accumulates-> Limits the design of the search space Challenges and our approachC1: How to build a large search space automatically?•Use a hierarchical search space •Sample complete programs and fine-tune themC2: How to search efficiently?Fine-tuningBetter Programs Low-level detail sampling ......fori.0 in range(64):for j.0 inrange(64):for k.0 inrange(512):fori.1 in range(8):for j.1 inrange(8):D[...] = ... CompletePrograms ...for ...for ...for ...for ... ...for ...for ...for ...for ... ...for ...for ...for ...for ... High-levelstructure generation? ?? ?? Challenges and our approach •C3: How to allocate resource for many search tasks?•Utilize a task scheduler to prioritize important tasks Layer 1Layer 2 Layer 49Layer 50 Layer 3... Need to generate programs for all layers -> A lot of search tasks System Overview Deep Learning Models Subgraph 1TaskSchedulerSubgraph 2Subgraph 3·· · Program SamplerSketch GenerationRandom Annotation Performance TunerEvolutionary SearchLearned Cost Model Intel CPUMeasurerARM CPUNVIDIA GPU·· · Partitioned subgraphs One subgraph A batch of initial programs A batch of optimized programs Execution time of programs Program Sampling Deep Learning Models Subgraph 1 TaskScheduler Subgraph 2 Subgraph 3 ·· · Program Sampler Sketch Generation Random Annotation Performance Tuner Evolutionary Search Learned Cost Model Intel CPU Measurer ARM CPU NVIDIA GPU ·· · Partitioned subgraphs One subgraph A batch of initial programs A batch of optimized programs Execution time of programs •Goal: automatically construct a large search space and uniformly sample from the space•Approach•Two-level hierarchical search space: Sketch+ Annotation•Sketch: a few good high-level structures•Annotation: billions of low-level details Program Sampling ComputeDeclarationRule-basedSketch GenerationSketch 1Sketch 2... Random AnnotationCompletePrograms •Sampling process: Sketch Generation Examples 1/2 for i.0 in range(TILE_I0): for j.0 in range(TILE_J0): fori.1 in range(TILE_I1): for j.1 in range(TILE_J1): for k.0 in range(TILE_K0): fori.2 in range(TILE_I2): for j.2 in range(TILE_J2): for k.1 in range(TILE_I1): fori.3 in range(TILE_I3): for j.3 in range(TILE_J3): C[...] += A[...] * B[...] fori.4 in range(TILE_I2 * TILE_I3): for j.4 in range(TILE_J2 * TILE_J3): D[...] = max(C[...], 0.0) Generated sketch 1 * The mathmeticalexpression: !",$ =&'[",)] , × /[),$] 0",$ =max (!",$ ,0.0) where0≤",$,)<512 * The corresponding naïve program: foriin range(512): for j inrange(512): for kinrange(512): C[i, j] +=A[i, k] * B[k, j] foriinrange(512): for jinrange(512): D[i, j] =max(C[i, j], 0.0) * The corresponding DAG: Example Input 1: A B C D Derivation: “SSRSRSS” multi-level tiling + fusion Sketch Generation Examples 2/2 Random Annotation Examplesparalleli.0@j.0@i.1@j.1 in range(256): for k.0 inrange(32): fori.2 in range(16): unroll k.1 inrange(16): unrolli.3 in range(4): vectorizej.3 inrange(16): C[...] +=A[...] * B[...] fori.4 inrange(64): vectorizej.4 inrange(16): D[...] =max(C[...], 0.0) Sampled program 1 paralleli.2 in range(16): forj.2 in range(128): for k.1 inrange(512): for i.3 in range(32): vectorizej.3 inrange(4): C[...] +=A[...] * B[...] paralleli.4 inrange(512): for j.4 inrange(512): D[...] = max(C[...], 0.0) Sampled program 2 fori.0 in range(TILE_I0): for j.0 inrange(TILE_J0): fori.1 in range(TILE_I1): for j.1 inrange(TILE_J1): for k.0 inrange(TILE_K0): fori.2 in range(TILE_I2): for j.2 inrange(TILE_J2): for k.1 inrange(TILE_I1): fori.3 in range(TILE_I3): for j.3 inrange(TILE_J3): C[...] +=A[...] * B[...] fori.4 inrange(TILE_I2 * TILE_I3): for j.4 inrange(TILE_J2 * TILE_J3): D[...] = max(C[...], 0.0) Generated sketch 1 paralleli.0@j.0@i.1@j.1 in range(256): for k.0 inrange(32): fori.2 in range(16): unroll k.1 inrange(16): unrolli.3 in range(4): vectorizej.3 inrange(16): C[...] +=A[...] * B[...] fori.4 inrange(64): vectorizej.4 inrange(16): D[...] =max(C[...], 0.0) Sampled program 1 paralleli.2 in range(16): forj.2 in range(128): for k.1 inrange(512): for i.3 in range(32): vectorizej.3 inrange(4): C[...] +=A[...] * B[...] paralleli.4 inrange(512): for j.4 inrange(512): D[...] = max(C[...], 0.0) Sampled program 2 fori.0 in range(TILE_I0): for j.0 inrange(TILE_J0): fori.1 in range(TILE_I1): for j.1 inrange(TILE_J1): for k.0 inrange(TILE_K0): fori.2 in range(TILE_I2): for j.2 inrange(TILE_J2): for k.1 inrange(TILE_I1): fori.3 in range(TILE_I3): for j.3 inrange(TILE_J3): C[...] +=A[...] * B[...] fori.4 inrange(TILE_I2 * TILE_I3): for j.4 inrange(TILE_J2 * TILE_J3): D[...] = max(C[...], 0.0) Generated sketch 1 PerformanceFine-tuning Deep Learning Models Subgraph 1 TaskScheduler Subgraph 2 Subgraph 3 ·· · Program Sampler Sketch Generation Random Annotation Performance Tuner Evolutionary Search Learned Cost Model Intel CPU Measurer ARM CPU NVIDIA GPU ·· · Partitioned subgraphs One subgraph A batch of initial programs A batch of optimized programs Execution time of programs Evolutionary Search•Random sampling does not guarantee the performance•Perform evolutionary search with learned cost model on sampled programs•mutation •crossover+ = •Randomly mutate tile size•Randomly mutate parallel/unroll/vectorize factor and granularity•Randomly mutate computation location •Predict the score of each non-loop innermost statementfor i in range(10):for j in range(10):B[i][j] = A[i] * 2for i in range(10):C[i] = B[i][i] -3Statement B:Statement C: Example: Cost = Cost of Statement B + Cost of Statement C •Extract features for every non-loop innermost statement:•used cache lines, used memory, reuse distance, arithmetic intensity, ...•Train on-the-fly with measured programs (typically less than 30,000) Learned Cost Model TaskScheduler Deep Learning Models Subgraph 1 TaskScheduler Subgraph 2 Subgraph 3 ·· · Program Sampler Sketch Generation Random Annotation Performance Tuner Evolutionary Search Learned Cost Model Intel CPU Measurer ARM CPU NVIDIA GPU ·· · Partitioned subgraphs One subgraph A batch of initial programs A batch of optimized programs Execution time of programs Task Scheduler•There are many subgraphs(search tasks) in a network•Example: ResNet-50 has 29 unique subgraphs after partition •Predict each task’s impact on the end-to-end objective function•Using optimistic guess and similarity between tasks Task 1 Task 2 Task 3 •Existing systems: sequential optimization with a fixed allocation •Our task scheduler: slice the time and prioritize important subgraphsTask 1Task 2Task 3Task 1Task 2Task 1Task 3Task 1 EvaluationResultsThree levels : single operator, subgraph and network Single OperatorPlatform:Intel-Platinum 8124M (18 cores)Operators:conv1d (C1D), conv2d (C2D),conv3d (C3D), matmul (GMM)group conv2d (GRP),dilated conv2d (DIL)depthwise conv2d (DEP), conv2d transpose (T2D),capsule conv2d (CAP),matrix 2-norm (NRM) Analysis: For most test cases, the best programs found by Ansor areoutside the search space of existing search-based frameworks. Parallelize reduction loops Unroll to simplify the multiplication of zeros in the strided caseExplore more tiling levels and computation locations SubgraphPlatforms:"@C" for Intel CPU (8124M)"@G" for NVIDIA (V100)Subgraphs:ConvLayer = conv2d + bn + reluTBS = transpose + batch_matmul + softmax Analysis:Comprehensive coverage of the search space gives 1.1–14.2×speedup against the best alternative. Network Analysis •Ansor performs best or equally the best in all test cases with up to 3.8xspeedup Platforms:Intel CPU (8124M)NVIDIA GPU (V100)ARM CPU (A53)Networks: ResNet-50, Mobilenet V2, 3D-ResNet, DCGAN, BERT Intel CPU NetworkPlatforms:Intel CPU (8124M)NVIDIA GPU (V100)ARM CPU (A53)Networks: ResNet-50, Mobilenet V2, 3D-ResNet, DCGAN, BERT Analysis •Ansor performs best or equally the best in all test cases with up to 3.8xspeedupNVIDIA GPU NetworkPlatforms:Intel CPU (8124M)NVIDIA GPU (V100)ARM CPU (A53)Networks: ResNet-50, Mobilenet V2, 3D-ResNet, DCGAN, BERTARM CPU Analysis •Ansor performs best or equally the best in all test cases with up to 3.8xspeedup•Ansor delivers portable performance Ablation Study Analysis•The most important factor is the search space•Fine-tuning improves the search results significantly•Task scheduler accelerates the search•Match the performance of AutoTVM with 10x less search time AnsorAnsor w/o task schedulerAnsor w/o fine-tuning Ansor w/o large search spaceBaseline (AutoTVM) Summary•Search-based compilation enables to generate high-performance tensor programs for deep learning•Ansor introduces techniques to improve the search in three aspects:•Large search space•Efficient search algorithm•Smart search scheduling •Thank you for listening•Email me to ask follow-up questions: lianminzheng@gmail.com Rapidly Selecting Good Compiler Optimizations using Performance Counters John Cavazos1 Grigori Fursin2 Felix Agakov1 Edwin Bonilla1 Michael F.P. O’Boyle1 Olivier Temam2 Members of HiPEAC 1Institute for Computing Systems Architecture (ICSA) School of Informatics, University of Edinburgh, UK 2ALCHEMY Group, INRIA Futurs and LRI, Paris-Sud University, France Abstract Applying the right compiler optimizations to a particu- lar program can have a significant impact on program per- formance. Due to the non-linear interaction of compiler optimizations, however, determining the best setting is non- trivial. There have been several proposed techniques that search the space of compiler options to find good solutions; however such approaches can be expensive. This paper pro- poses a different approach using performance counters as a means of determining good compiler optimization settings. This is achieved by learning a model off-line which can then be used to determine good settings for any new program. We show that such an approach outperforms the state-of- the-art and is two orders of magnitude faster on average. Furthermore, we show that our performance counter-based approach outperforms techniques based on static code fea- tures. Using our technique we achieve a 17% improve- ment over the highest optimization setting of the commer- cial PathScale EKOPath 2.3.1 optimizing compiler on the SPEC benchmark suite on a recent AMD Athlon 64 3700+ platform. 1 Introduction Automatically selecting the best set of compiler op- timizations for a particular program is a difficult task and there has been much previous work on automatically searching for the best optimization settings [14, 22, 23, 29]. This previous work is based on iteratively enabling certain optimizations, running the compiled program and, based on its performance, deciding on a new optimization setting. Pan et al. [22] introduce a new algorithm called combined elimination (CE) that was shown to outperform all previ- ous search-based techniques in finding good optimization settings with considerably fewer evaluations. However, these pure search or “orchestration” ap- proaches do not use prior knowledge of the hardware, com- piler, or program and instead attempt to obtain this knowl- edge online. Thus, every time a new program is optimized, the system starts with no prior knowledge. In our experi- ments, this means on average over 600 evaluations (com- pile + run) to tune an application. In contrast, the technique presented in this paper uses knowledge about a program’s behavior to automatically select the best optimizations with as little as 3 program evaluations. Specifically, we use the performance counter values collected from a few runs of the program as input to an automatically constructed model which outputs a probability distribution of good compiler optimizations to use. Using dynamic knowledge of how a particular program runs on a particular platform, on a set of benchmark suites we are able to achieve the same per- formance or better as combined elimination, two orders of magnitude faster on average. Thus, obtaining knowledge a- priori (involving a one-off-cost at the factory), we can sig- nificantly speedup the searching of good optimization se- quences for any new program. In contrast, “pure search” techniques always obtain knowledge online and must do so for any new program they optimize. Performance counters have been extensively used for performance analysis in explaining program behavior [10, 3]. One of the first papers to investigate how they could be used systematically to select optimizations [24] showed impressive performance gains. However, the heuristic used was manually developed over a 12 month period using de- tailed simulations. Furthermore, the optimizations selec ted were also implemented by hand. A small change in the ar- 0 5 10 15 20 25 30 35 40 L2_TCA L1_TCH L1_TCM FP_OPS FAD_INS FML_INS L1_TCA L2_TCH L1_ICR L2_ICA L1_ICA L2_ICH L1_ICH L2_DCW L2_DCR L2_DCA L1_DCA L2_DCH L1_DCH TOT_CYC RES_STL VEC_INS BR_INS FP_INS BR_MSP BR_TKN HW_INT STL_ICY L2_STM L2_LDM L1_STM L1_LDM TLB_TL TLB_IM TLB_DM FPU_IDL L2_TCM L2_ICM L2_DCM L1_ICM L1_DCM Relative to Average Perf Cntrs 181.mcf Figure 1. Performance counter values for 181.mcfcompiled with -O0 relative to the aver- age values for the entire set of benchmark suite (SPECFP,SPECINT, MiBench, Polyhedron). FAST PC Model 0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2 L2_TCAL1_TCHL1_TCMFP_OPSFAD_INS FML_INSL1_TCAL2_TCH L1_ICRL2_ICAL1_ICA L2_ICHL1_ICHL2_DCW L2_DCRL2_DCAL1_DCA L2_DCHL1_DCHTOT_CYC RES_STLVEC_INSBR_INSFP_INSTOT_INSBR_MSP BR_TKNHW_INTSTL_ICY L2_STML2_LDML1_STML1_LDMTLB_TLTLB_IM TLB_DMFPU_IDLL2_TCM L2_ICML2_DCML1_ICM L1_DCM Relative to −o0 Perf Cntrs 181.mcf Figure 2. Performance counter values of -Ofast (FAST) and our scheme (PCModel) relative to - O0 for each performance counter for 181.mcf. chitecture would potentially require the entire process to be repeated. In contrast, our scheme is entirely automatic. It uses machine learning to automatically build a model which maps performance counters to good optimization options without human intervention and is thus portable. The use of learned models to guide the selection of op- timizations has also received recent attention [1, 5, 27]. Stephenson et al. [27], for instance, use a genetic program- ming approach to automatically learn individual compiler optimizations, such as the register allocation spill heuristic, within the Trimaran compiler. In this paper, however, we consider the problem of determining the best settings for a large number of optimizations within a highly-tuned com- mercial compiler, PathScale EKOPAth 2.3.1 [25] whose performance is as good as or better than Intel 9.0. We show significant performance improvements over the highest op- timization level for this compiler. In our previous work [1], we used static code features to obtain good optimizations for new programs being com- piled. The static features were used to find the most similar program from a set of previously explored programs. This was used for estimating a distribution of good sequences for the matching program, from which optimizations to ap- ply for the new program were drawn. The idea is that opti- mizations which performed well on a “similar” (previously explored) program will work well for the new program be- ing compiled. This approach worked well on multimedia kernels on embedded processors, but as we show in Sec- tion 5.3 it performs poorly on larger general purpose appli- cations. In fact, there is little or no performance improve- ment over the highest optimization level provided by the PathScale compiler. The main reason is that static code fea- tures, which essentially characterize local code construc ts such as loops, provide a poor global characterization once aggregated over many such code sections. Furthermore, code features are a poor mechanism to describe the dynamic behavior of large control-flow intensive programs. We show that a performance counter-based scheme overcomes these challenges. Using performance counters to select good op- timizations is attractive as it exploits knowledge of the pro- gram’s behavior without requiring knowledge of the pro- gramming language syntax. This paper is organized as follows. The next section provides a motivating example showing that performance counters can be used to select good optimizations. Sec- tion 3 describes the performance counters used in this pa- per and how they can characterize program behavior. This section also includes a brief description of how we use a simple modelling technique, logistic regression[4], to auto- matically learn a global optimizing heuristic. Section 4 de - scribes the experimental setup and is followed in Section 5 by the experimental results and their analysis. This includes a comparison between our scheme and both combined elim- ination and random selection. We also compare against a static feature-based modelling approach. This is followed by a summary of related work and concluding remarks. 2 Motivation The information obtained from performance counters is a compact summary of a program’s dynamic behavior. In particular, they summarize important aspects of a program’s performance, e.g., cache misses or floating point unit uti- lization. Our approach uses this information to automati- cally select compiler optimization settings likely to improve program performance. This section looks at just one of the programs evaluated in this paper to illustrate how such performance counters can be used to select good compiler optimizations. As the performance counter values are related to actual program performance, they can be used by a modelling technique Compiler Evaluations Execution time Speedup -O0 1 40.2 1 -Ofast 1 32.3 1.24 CE 240 18.0 2.23 PC Model 3 17.2 2.33 Figure 3. The execution time and speedup over -O0 for the best compiler setting ob- tained using different schemes on 181.mcf. The column labelled Evaluations shows the number of times the code must be run to achieve this level of performance by each scheme. (described in the next section) to select good optimization settings. Our model examines performance counter values of a new program and, using prior knowledge from previ- ously examined programs, determines the optimization set- ting most likely to result in a speedup and improved perfor- mance counter values. 2.1 Performance Counters Figure 1 illustrates the use of performance counters. This graph shows the performance counter values for the 181.mcfbenchmark relative to the average values for the SPEC benchmark suite. These values were collected on an AMD Athlon 64 3700+ processor using the commercially available PathScale optimizing compiler. What is immedi- ately apparent is that 181.mcf is an unusual program - having a much greater number of memory accesses per in- struction than average - up to 38 times more in the case of L2 store misses (L2 STM). A learned model should iden- tify this and enable transformations that reduce the impact of cache accesses. Figure 2 shows the performance counter values after applying two optimization schemes, -Ofast (FAST), the highest optimization setting available with PathScale and the setting found by our performance counter model ( PC- Model). PCModel is able to significantly improve the use of the L1 and L2 cache. This is shown in the third to the last and the last bars of Figure 2 in the columns labelled L1 TCM (L1 total cache miss) and L2 TCA (L2 total cache accesses). These bars show that the model is able to reduce the number of L1 cache misses by 20% which has the effect of reducing the number of L2 accesses by 20%. The -Ofast setting, on the other hand, has no effect on these values. 2.2 Performance Figure 3 shows the speedups obtained by -Ofast, CE, and PCModel over -O0. -Ofast is able to achieve a 1.24 speedup over -O0 while PCModel gives a speedup of 2.33, i.e., a speedup of 1.88 over -Ofast. It achieves this perfor- mance improvement with just 3 evaluations using a learned model trained offline. If we compare this to the performance of combined elimination (CE) [22], our scheme gives a slightly greater improvement. Furthermore, combined elim- ination requires 240 evaluations on this benchmark. Using our trained model, we are able to achieve greater perfor- mance improvement over the state-of-the-art, approaching two orders of magnitude fewer evaluations. 2.3 T ransformations Examining the transformations selected by PCModel, it is apparent that locality enhancing loop optimizations hav e been enabled. In effect, the automatically generated model has learned that 181.mcfhas a problem with its memory usage and has selected transformations to overcome this. If, however, we examine the transformations selected by - Ofast and PCModel we see that they both enable the loop optimizer -LNO which is aimed at exploiting locality. On closer inspection, the major difference is that our model de- cides to turn on the -m32 flag, i.e., generate 32-bit code rather than the default 64-bit for the AMD. It does this be- cause the number of data cache accesses and branch instruc- tions are high. Figure 1 shows that the data cache accesses are relatively high (L1 DCM and L2 DCM) for this bench- mark. Also, looking at the number of branch instructions (BR INS) we see it is more than 2.5 times the average. According to the AMD compiler manual [2] the -m32 option “can improve performance if your program has lots of variables of the type long and/or pointers. As these data- types are 32-bit in x86, this switch will reduce the memory footprint of your program.” We note that -m32 is only use- ful for a few programs, and our model decides based on the dynamic characteristics (performance counters) of each program when it should be applied. In fact, many manu- facturers include the -m32 option in the SPEC “peak” flags for some codes when using PathScale. By examining the code of 181.mcfwe see it accesses its main data structure through pointers in a loop. Also, it has a large number of branches executed proportional to the number of total in- structions due to small tight loops. Reducing the pointer size, by using -m32, reduces the number of I-cache data misses dramatically for 181.mcf as can be seen in Fig- ure 2. Thus, our model has learned that data cache misses and branch instructions (via the performance counter data) are the critical characteristics of this program and suggests t he compiler convert pointers from 64-bit to 32-bit, because 64- bit pointers are reducing the effective cache capacity and memory bandwidth. This demonstrates the strength of au- tomatic model construction. It has no a priori human bias 0 0.5 1 1.5 2 2.5 L2_TCA L1_TCH L1_TCM FP_OPS FAD_INS FML_INS L1_TCA L2_TCH L1_ICR L2_ICA L1_ICA L2_ICH L1_ICH L2_DCW L2_DCR L2_DCA L1_DCA L2_DCH L1_DCH TOT_CYC RES_STL VEC_INS BR_INS FP_INS BR_MSP BR_TKN HW_INT STL_ICY L2_STM L2_LDM L1_STM L1_LDM TLB_TL TLB_IM TLB_DM FPU_IDL L2_TCM L2_ICM L2_DCM L1_ICM L1_DCM Relative to Average Perf Cntrs SPEC FP Figure 4. Performance counter values for SPEC FP average values for the entire benchmark suite compiled with -O0. 0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 L2_TCA L1_TCH L1_TCM FP_OPS FAD_INS FML_INS L1_TCA L2_TCH L1_ICR L2_ICA L1_ICA L2_ICH L1_ICH L2_DCW L2_DCR L2_DCA L1_DCA L2_DCH L1_DCH TOT_CYC RES_STL VEC_INS BR_INS FP_INS BR_MSP BR_TKN HW_INT STL_ICY L2_STM L2_LDM L1_STM L1_LDM TLB_TL TLB_IM TLB_DM FPU_IDL L2_TCM L2_ICM L2_DCM L1_ICM L1_DCM Relative to Average Perf Cntrs MiBench Figure 5. Performance counter values for MiBench average values for the entire bench- mark suite compiled with -O0. about what are important program characteristics or trans- formations – it learns solely based on empirical evidence. This example show that performance counters can be used by a model to select optimizations that improve per- formance by examining the values of the counters. Further- more, it can find good sequences rapidly. The next sec- tions describe the performance counters used in this paper in greater detail and explains the technique used to automat- ically build an automatic optimizing heuristic. 3 Optimization selection based on performance counters This section first looks at the performance counters used in this paper and illustrates that they can be used to char- acterize well-known properties of SPEC FP and MiBench. This is followed by a description of the modelling technique we use which is based on logistic regression. This is a stan- dard machine learning technique which can learn whether an optimization is good or bad for a certain set of perfor- mance counter values and associates a probability with this decision. 3.1 Dynamic characterization of program behavior using performance counters Modern processors are often equipped with a special set of registers that allow for measuring performance counter events with no disruption to the running program. These events can describe several characteristics of the running program, such as, cache hits and misses and branch pre- diction statistics. On the AMD Athlon, there are 4 regis- ters for measuring performance counter events, but up to 60 different events can be measured. It is possible to col- lect anywhere between 4 and 60 types of events per run by multiplexing the use of the special registers. Since we aim at broadly characterizing the program behavior rather than studying a particular performance phenomenon, we have collected all 60 events. Using multiplexing, we collected all 60 performance counter values of a benchmark in 3 runs. The performance counters used in this study are shown in Table 1. In order to use the collected statistics as inputs to our model, we normalized the value of each performance counter by TOT INS, the total number of instructions exe- cuted. Normalizing the performance counters is important since it allows us to generalize across different benchmarks regardless of how long each benchmark executes. Table 1 also presents the average values for each counter across our benchmark suites. As can be seen, some counter events are relatively common, such as L1 data cache misses (L1 DCA) while others are relatively rare, such as instruc- tion TLB misses (TLB IM). To see how the performance counters can character- ize program behavior, we have examined two benchmark suites, SPEC FP and MiBench, out of the four benchmark suites we evaluated (SPEC INT, SPEC FP, MiBench, Poly- hedron). We plotted the performance counter values for each of these suites relative to the average values for the entire collection of benchmarks. These values are shown in Figures 4 and 5 where the values are collected when com- piled with -O0. It is interesting to see that MiBench exer- cises the cache hierarchy much less than SPEC FP which can be seen by the much larger number of L2 cache misses (L2 TCA) for SPEC FP. Also, MiBench has a relatively large number of branches compare to SPEC FP, almost twice as many, and many of the branches in MiBench are mispredicted, while more branches for SPEC FP codes are easier to predict (BR MSP). These results are not surprising and have been discussed in prior work. However, these graphs show that there are important aspects of program behavior that can be captured using performance counters. Furthermore, this informatio n can serve as an input to a model that selects compiler op- Performance Counter Name Meaning Average Values HW INT Hardware interrupts 0.000 RES STL Cycles stalled on any resource 0.660 STL ICY Cycles with no instruction issue 0.035 TOT CYC Total cycles 1.099 TOT INS Instructions completed 1.000 VEC INS Vector/SIMD instructions 0.017 Floating Point Instruction Statistics FAD INS, FML INS, FP INS, FP OPS, FPU IDL Floating point: Adds, Multiplies, Total Insns, Total Ops, Cycles Idle 0.030, 0.036, 0.066, 0.066, 0.473 Branch Instruction Statistics BR INS, BR MSP, BR TKN Branch instructions, Cond. Branches Mispredicted, Cond. Branches Taken 0.047, 0.002, 0.035 Level 1 Cache Statistics DCA, DCH, DCM Data Cache: Accesses, Hits, Misses 0.475, 0.472, 0.004 ICA, ICH, ICM, ICR Instruction Cache: Accesses, Hits, Misses, Reads 0.316, 0.315, 0.0006, 0.315 LDM, STM Load Misses, Store Misses 0.0015, 0.0016 TCA, TCH, TCM Total Cache: Accesses, Hits, Misses 0.789, 0.790, 0.004 Level 2 Cache Statistics DCA, DCH, DCM, DCR, DCW Data Cache: Accesses, Hits, Misses, Reads, Writes 0.003, 0.003, 0.0005, 0.0015, 0.0016 ICA, ICH, ICM Instruction Cache: Accesses, Hits, Misses 0.0006, 0.0006, 0.000002 LDM, STM Load Misses, Store Misses 0.0004, 0.00008 TCA, TCH, TCM Total Cache: Accesses, Hits, Misses 0.004, 0.003686, 0.0005 TLB Statistics TLB DM Data translation lookaside buffer misses 0.0002 TLB IM Instruction translation lookaside buffer misses 0.000001 TLB TL Total translation lookaside buffer misses 0.0002 Table 1. Performance counters used. The first column lists th e performance counter acronyms, the second column gives a description, and the third column give s the average counter values normal- ized by total instructions executed across the entire set of benchmark suites. timizations. Using these statistics our model can learn to apply optimizations that will reduce the impact of cache misses for SPEC FP or branch misses for MiBench. The next section shows how we can use this information to se- lect good optimizations automatically using machine learn- ing. 3.2 Automatically learning a good model The goal of model construction is to learn a mapping x → t between a set of performance counters featuresx, and a set of good optimizations t. Here x is a vector of the 60 normalized performance counters values, and t is a vector mask indicating which transformations are used in the se- quence (i.e., each vector entry corresponds to a transforma- tion, and t corresponds to a sequence of 0/1, 1 meaning the transformation is used). The goal of the model is to pre- dict the best possible t for a program described by features x. We emphasize this is not the phase-ordering problem. That is, our models do not find the best order in which to apply transformations. While this is an interesting problem, most compilers do not allow changing arbitrarily the order optimizations are applied. In the following paragraphs, we first describe how the training set required for offline training is collected whic h is then used to construct a model. We then describe how this model is used. Training set At first, a large number (500) of transformation sequences are randomly sampled and applied to each program and the speedup for each of these sequences is recorded. Also, we require three additional runs of the program to collect the performance counter values. The runs where the speedup, relative to -Ofast, is smaller than 1 are filtered out, and the remaining data forms the training set. Then, we use the standard Leave One Out Cross-Validationprocedure for evaluating our models. That is, the models are trained on N −1 benchmarks and tested on the Nth benchmark that has been left out. In our experiments, N = 57, therefore our models were trained with 56 ×500 = 28000 training data points. The cost of obtaining 28000 training points is ex- pensive, however it is a one-off-cost incurred offline at the factory. Model construction The model is now built using the training set. The predic- tive modelling process is summarized in Figure 6. We use a probabilistic approach for predictive modelling, where we determine for each optimization ti the probability pi that it should be evaluated. The technique used is logistic regres- sion [4]. Intuitively, it attempts to find the set of perfor- mance counter values for which enabling the transforma- tion ti leads to improved performance in the training set and also determines when disabling a transformation is prefer- able. In effect, it tries to draw a hyperplane in the multi- dimensional hardware counter space between those occa- sions when the transformation is best enabled and those occasions when it is best disabled. Borderline cases near the hyperplane have a probability, p, around 0.5 associ- ated with them. Those which should be definitely enabled have p >> 0.5 and those which should be definitely dis- abled have p << 0.5. This is a standard machine learning technique and is computationally inexpensive - see [4] for a more detailed description. Note that gathering training data and construction of the model is an offline process, that is, it would take place “at the factor” before the compiler is shipped to the costumer. Using the model Given a new target benchmark, we first extract the perfor- mance counter features x by running the benchmark. This requires 3 runs of the benchmark. This features vector is then fed as input to our trained models which then outputs a probability pi for each transformation ti showing whether each transformation should be applied or not. We then sam- ple from this probability distribution to generate a suitab le compiler optimization setting. The program is then opti- mized based on the transformations selected and the new speedup is measured as shown in Figure 6. An advantage of this technique is that we can sample as many times as we wish to generate different settings. We later show in Section 5.1 that very few samples are required to achieve good performance. Furthermore, increasing the number of samples which are evaluated increases the performance ob- tained. 4 Experimental Setup This section briefly describes the experimental setup. First, the hardware platform, OS, and optimizing compiler are described. Second, we describe the benchmarks and the optimizations available for selection. 4.1 Platform We perform all experiments on a cluster of AMD Athlon 64 3700+ 2.4GHz processors with an L1 cache of 64KB, an L2 cache of 1MB, 3GB of memory, and each running Mandriva Linux 2006. We use the latest PAPI 3.2.1 hard- ware counter library [21] and PAPIEx 0.99rc2 tool to collect hardware performance counters for the benchmarks. Ta- ble 1 has a brief description of all the counters we use. PA- PIEx works in the multiplexing mode allowing us to col- lect a large number of counters in one run. We collect performance counters using level -O0 so that characteris- tics of a benchmark are not masked by higher optimization levels (e.g., -Ofast). We use the latest open-source com- mercial PathScale EKOPath Compiler 2.3.1 [25] with the -Ofast flag, which we refer to as our baseline. This com- piler is tuned to AMD processors and on average performs similarly or better than the Intel 9.0 compilers on the same platform. In order to evaluate the stability of our measurements, we have executed multiple runs of each benchmark using -Ofast and have found there to be very little variance in the execution time, on average less than 0.3%. 4.2 Benchmarks We evaluate our approach on widely-used benchmark suites written in C, C++, Fortran and Fortran 90. These are SPEC 95 FP (ref dataset), SPEC 2000 FP and INT (train dataset), Polyhedron 2005 [18], and MiBench [13]. We used train inputs for the SPEC 2000 benchmarks due to the large number of experiments we ran, on average over 1000 for each benchmark. SPEC and Polyhedron bench- marks are relatively large programs used for performance evaluation of servers and for comparison of performance of various compilers on these servers. These benchmarks are used by PathScale to tune their compiler suite. MiBench is a free, commercially representative embedded benchmark suite consisting of a large number of applications and ker- nels. We believe that all these programs cover a large vari- ety of different dynamic behaviors. In the experimental sec- tion, we partition the benchmark results into SPEC, which includes all SPEC benchmarks and Others, which includes MiBench and Polyhedron. 4.3 T ransformations The PathScale EKOPath compiler suite includes a PathOpt tool that randomly selects from a variety of global compiler settings. PathOpt iterates for a user-specified amount of evaluations and is used to iteratively find the best optimization settings for a program on a targeted platform. We select 121 flags that are known to influence performance and use PathOpt to apply 500 random settings of these flags on all benchmarks. We also allow our model to generate sequences with optimizations that are mutually exclusive, e.g, different unroll factors. When this happens, the com- piler simply ignores all but the last option. We could have easily adapted our models to handle this directly (e.g., us- ing a soft-max approach where the optimization with the New program predicted set of best transformations Architecture (t A 1 t A 2 … t A M ) (t B 1 t B 2 … t B M ) TB (baseline option) X performance counter features for the baseline PCModel (b) Inference using a predictive model. Given a new benchmark, we first extract per formance counter features. These features are then fed into our trained models which then output a set of transformation sequences to apply to the new benchmark. … best speedups … sA sB Programs (training set) bes t set of transformations (option sequences) Architecture (t 1 t 1 2 … t 1 M ) (t 2 1 t 2 2 … t 2 M ) … (t N 1 t N 2 … t N M ) … TB (baseline option) s1 s2 sN Speedups … X performance counter features for the baseline PCModel (a) Summary of the predictive modelling procedure. We use the features x, the transfor mations t, and (implicitly) the speed -ups {s} for constructing the training data < x , t > . We then evaluate the mapping from the performance counters to the transformation sequences x t by fitting a probabilistic model to the training set. Figure 6. Training and using the models. highest probability is chosen), however this would make it harder to compare with combined elimination and random. The speedups for each setting were used along with perfor- mance hardware counters as training data for our logistic regression model. 5 Experimental results In this section we evaluate our proposed technique in a number of ways. Initially, we report the performance im- provement achieved by our technique compared to com- bined elimination and the number of evaluations each scheme needs to achieve such a level of performance. Since we use a probabilistic model we have generated our re- sults for multiple trials. For random selection, we have also generated our results for multiple trials. This is then fol- lowed by a comparison of the performance of a number of different schemes with respect to the number of eval- uations available. Here, we compare combined elimina- tion (CE), our models (PCModel), and a random selec- tion (RAND) approach which generates random transfor- mation sequences. RAND is implemented using a pseudo- random number generator to choose which optimizations to apply in the sequence. Each optimization has a .5 proba- bility of being used in each sequence. We then provide a study examining the use of static code features as a means of selecting compiler optimizations. Finally, we perform some analysis to evaluate the most important performance counter features. All results in this section, unless other - wise stated, are relative to -Ofast, the highest optimizati on level available in PathScale. Note, all of our techniques (CE,PCModel,Random) start with the -Ofast as their initial sample, so none of our techniques can perform worse than -Ofast. We emphasize that our models are built using leave- one-out cross validation, so the models are not trained using any information of the programs it is optimizing. CE PC Model 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 average 301.apsi 300.twolf 256.bzip2 197.parser 191.fma3d 189.lucas 188.ammp 186.crafty 183.equake 181.mcf 179.art 178.galgel 177.mesa 175.vpr 173.applu 172.mgrid 171.swim 168.wupwise 164.gzip 146.wave5 141.apsi 125.turb3d 110.applu 107.mgrid 104.hydro2d 103.su2cor 102.swim 101.tomcatv Relative to −ofast Combined Elimination (CE) and PC Model Figure 7. The speedup of Combined Elimina- tion (CE) versus our model (PCModel) for the SPEC benchmarks relative to the performance of -Ofast. The number of evaluations used by PCModel is limited to 25 while CE uses on aver- age 609. CE PC Model 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 average tfft test_fpu gsm CRC32 adpcm_c sha rijndael rnflow protein pix stringsearch patricia dijkstra mdbx linpk gas_dyn fatigue drag doduc lame jpeg_d jpeg_c channel susan_s susan_e susan_c bitcount air ac Relative to −ofast Combined Elimination (CE) versus PC Model Figure 8. The speedup of Combined Elimination (CE) versus our model (PCModel) for the Other (non-SPEC) benchmarks relative to the perfor- mance of -Ofast. The number of evaluations used by PCModel is limited to 25 while CE uses on average 609. 5.1 Speedup and number of evaluations for PCModel and CE Figure 7 shows the speedups of our model and combined elimination relative to -Ofast on the SPEC benchmarks. PC- Model achieves a speedup of 1.17 on average compared to 1.09 by CE. In this example, we have set the number of evaluations selected by our model to 25 evaluations. How- ever, CE needs on average 609 evaluations of the program to achieve this. We note that both PCModel and CE can find significant improvements for several programs. For in- stance, PCModel finds improvements of 10% or more over -Ofast for half (14 of 28) of the SPEC benchmarks. Thus we are able to achieve better performance than CE with consid- erable fewer evaluations. In fact, our model achieves the same performance as CE on the SPEC benchmarks in only 3 iterations. Figure 8 shows a similar comparison for the other benchmarks. In this case both schemes give approx- imately the same performance improvement of 1.17. Fig- ure 9 however, shows that CE needs a large number of eval- uations to achieve this performance level, ranging form 240 evaluations up to 1550 with an average of 609 needed. It is not suprising that the CE algorithm requires a large number of evaluations. The CE algorithm first evaluates the effect of each of the optimizations by turning them off one at a time. This is 121 evaluations for the entire set of optimizations we explored. Then it “combines” the knowl- edge gathered by these initial evaluations to choose opti- mizations that lead to better improvement when turned off. After several iterations of turning off single optimizations it converges to a setting where no additional flags turned off improve performance. We refer the reader to the combined elimination paper [22] for further details of the algorithm. 5.2 Performance versus number of evaluations for different schemes To give a different view of how our model performs we considered the performance it achieves as a function of the number of evaluations we select from it. Figure 10 shows the performance achieved averaged across all the bench- marks versus the number of evaluations allowed. We also compare our approach relative to combined elimination and random selection. For each technique, the more evaluations allowed the better the performance achieved. Our model achieves the same performance after 60 evaluations as ran- dom does after 200 evaluations. Surprisingly, random se- lection does quite well! Other papers [15, 1] have reported on the excellent performance of pure random search. CE’s initial step involves turning off each optimization in turn which gives a small speedup of 1.04 across the first 121 evaluations. Only after all 121 optimizations have been evaluated does it improve its behavior by “combining” its results. However, after 200 evaluations it only achieves the same performance as that achieved by our model after 2 evaluations. Random selection achieves this in just 10 eval- uations. RAND and CE both found an improvement of 17% over -Ofast using 200 and 60 iterations, respectively. CE finds less improvement at 12%. We note that for these ex- periments the CE algorithm was run to completion. On the other hand, given the nature of the RAND and PCModel algorithms, we could continue to construct sequences with these algorithms until we are satisfied with the optimizied performance of our application. Both, RAND and PCModel whould reach the same maximum available speedup in the limit, however PCModel should reach that speedup sooner. We believe RAND and PCModel perform well in our ex- 0 200 400 600 800 1000 1200 1400 1600 PCModel-----------averagetffttest_fpugsmCRC32adpcm_csharijndaelrnflowproteinpixstringsearchpatriciadijkstramdbxlinpkgas_dynfatiguedragdoduclamejpeg_djpeg_cchannelsusan_ssusan_esusan_cbitcountairac301.apsi300.twolf256.bzip2197.parser191.fma3d189.lucas188.ammp186.crafty183.equake181.mcf179.art178.galgel177.mesa175.vpr173.applu172.mgrid171.swim168.wupwise164.gzip146.wave5141.apsi125.turb3d110.applu107.mgrid104.hydro2d103.su2cor102.swim101.tomcatv Iteration Count Combined Elimination and PC Model Iterations Figure 9. The number of evaluations of the CE algorithm per be nchmark. The mininum evaluations is 240 (181.mcf), maximum is 1562 (fatigue), and the average is 609. We compared CE to PCModel with an evaluation count 25 (far right). periments because the search space has many good points. However, in certain scenarios it is possible that CE could outperform RAND (and models trained with RAND data, such as PCModel). CE’s main goal is to eliminate opti- mizations that degrade performance. If we encouter an op- timization space with many optimizations that degrade per- formance of a benchmark, it would take a large number of iterations for RAND to construct a sequence with none (or few) of these degrading optimizations. 5.3 Static versus dynamic features As mentioned in the introduction, we previously used a model-based approach [1] to characterize programs using static code features. In this section, we quantitatively co m- pare the merit of static (code) versus dynamic (performance counter) features using the same number of evaluations. In previous work [1], we applied this approach to the UTDSP benchmarks, which are small embedded kernels often con- taining only a single loop nest with affine array accesses. Here, we extracted the same code features for several of the SPEC INT benchmarks, which are large control-flow inten- sive programs. We also used a K-nearest neighbor approach and built IID distributions similar to what we used in our previous work to be as fair as possible. We choose neigh- bors using either static code features or dynamic perfor- mance counter features and drew samples from the neigh- bor’s IID distribution to apply to a new program. The results of this experiment are shown in Figure 11. The static code feature-based approach finds some improve- ment in 4 of the 7 programs achieving an average speedups of just 1.01 when compared to -Ofast. In contrast, our performance counter model significantly improves over the static code feature-based approach giving a speedup aver- age of 1.08 over -Ofast. The graph shows performance counters are significantly better for characterizing large programs with complex control flow, e.g., 181.mcf and 186.crafty. 5.4 Analysis of the importance of the performance counters The goal of this analysis is to understand which perfor- mance counters are most important for predicting good opti- mization sequences. The fundamental objective in this con- text is mutual information between a subset of the perfor- mance counters and good optimization sequences (for defi- nition of mutual information, see e.g. [19]). Our goal was to maximize the mutual information for subsets of the retained features. In general, it is intractable to compute the mutual infor- mation exactly, therefore approximations need to be consid- 1 1.05 1.1 1.15 1.2 1.25 1 10 100 1000 Speedup Number of Evaluations Performance versus Number of Evaluations (PC Model, CE, RAND) PC Model RAND CE Figure 10. The speedup of Combined Elimina- tion (CE), PCModel, and random selection aver- aged across all benchmarks versus the number of program evaluations used. STATIC DYNAMIC 1 1.05 1.1 1.15 1.2 1.25 1.3 1.35 average 300.twolf 256.bzip2 197.parser 186.crafty 181.mcf 175.vpr 164.gzip Relative to −ofast Static vs Dynamic Features Figure 11. Performance of SPEC INT 2000 Benchmarks using static code features and dy- namic features. ered. For our analysis we applied a novel subset-selection approach which greedily maximizes the Gaussian approx- imation of the mutual information. For training data con- taining one good optimization sequence per benchmark, we found that over 95% of the total information (if all features are retained) was typically contained in just 15 performance counters. In contrast, conventional approximations disre - garding interactions between the inputs (e.g. [28]) would typically require twice as many features to retain the same amount of information, which in our case is not much bet- ter than random selection (see Figure 12 left). Interestingly, while the choice of the informative features generally de- pends on the training data, we found that there was a lot of overlap between the performance counters found for various good transformation sequences (typically with one or two unique features per training set). Figure 12 right shows in- formative performance counters for training sequences con- structed with the CE algorithm. 6 Related Work Parello et al. [24] presents a systematic, but manual it- erative approach for program optimization using dynamic features. At each iteration, performance counters are used to identify a performance anomaly of a program and a set of program transformations is suggested to solve this prob- lem. Then the transformed program is run again to detect further performance anomalies. The process is manual and can take several weeks per benchmark. Our technique is fully automated and can generate heuristics to predict good optimizations in seconds. In the area of predictive modelling, Zhao et al. use man- ually constructed cost/benefit models to predict whether to apply PRE or LICM[34]. They achieve 1% to 2% improve- ment over always applying an optimization, but at a cost of greatly increasing compilation time (by up to 68%). Their models appear to be quite complicated and have to be manu- ally constructed. Our models, on the other hand, are simple and automatically constructed using machine learning. During the past several years, the benefits of iterative compilation have been widely reported [15, 8, 9, 11, 14]. Iterative compilation is able to find optimization sequences that out-perform the highest optimization settings in com- mercial compilers and when applied to library subroutines they find solutions that compare favorably with highly- optimized hand-tuned vendor libraries [31, 12, 26, 30]. However, iterative compilation requires searching a com- binatorially large space defined by the optimizations of in- terest. This search can take several days to weeks depend- ing on the running time of the program, speed of the com- piler and target architecture, and thoroughness of the search. There have been a number of papers focusing on reducing the cost of iterative optimization. Kulkarni et al. [16] introduce the VISTA system, an interactive compilation system which concentrates on re- ducing compilation time. This system uses a variety of techniques to reduce the number of different compilation sequences evaluated. Their system stores a representation of each program compiled then detects when identical or equivalent code has been generated and only executes code that has not been previously generated. They also prohibit specific optimizations and optimization sequences from be- ing performed if it is unlikely that these optimizations wil l not change the code. These techniques are only effective when programs are extremely small, such as those used in embedded domains. Kulkarni et al. [17] also introduce techniques to allow exhaustive enumeration of all distinct function instances that would be produced from the different phase-orderings of 15 optimizations. This exhaustive enumeration allowed them to construct probabilities of enabling/disabling int er- 2 4 6 8 10 12 140 2 4 6 8 10 12 14 Retained PCs I({x},t) Feature Selection by Information Maximization Gaussian I({x},t) Gaussian I(xi,t) Quantized I(xi,t) Uniform Most Informative Performance Counters 1) L1 TCA 2) L1 DCH 3) TLB DM 4) BR INS 5) RES STL 6) TOT CYC 7) L2 ICH 8) VEC INS 9) L2 DCH 10) L2 TCA 11) L1 DCA 12) HW INT 13) L2 TCH 14) L1 TCH 15) BR MS Figure 12. Analysis of the importance of the performance counters. The data contains one good opti- mization sequence per benchmark. Left: Approximate amount of information retained in the selected features. Top curve: our method; lower curves: simpler heur istics. Conventional approach [28] which uses binning and ignores input interactions (dash-do tted curve) is comparable with the uni- form random selection. Right: 15 most informative performance counters sorted in the orde r of the descending importance. actions between the different optimization passes. Using these probabilities, they constructed a probabilistic batch compiler that determined which optimization should be ap- plied next depending on which one had the highest proba- bility of being enabled. This method however does not con- sider the benefits each optimization can potentially provide. In contrast, we train our model based on the impact of opti- mizations applied, and therefore our technique learns which optimizations are beneficial to apply to “unseen” programs with similar characteristics. Another system to speedup iterative compilation was recently introduced by Cooper et al. called ACME [7]. ACME utilizes a technique called estimated virtual execu- tion (EVE) which estimates changes to the execution counts of basic blocks when an optimization that changes the CFG is performed. This is done by inserting a pass into the opti- mization sequence after each invocation of a CFG-changing optimization and fixes the basic block counts based on the changes. They can then model the advantages and disad- vantages of applying optimizations by multiplying the num- ber of instructions in a block by its dynamic frequency then summing over all blocks. This technique can estimate the performance of very simple models, however this method is vastly inaccurate when estimating the performance of to- day’s complex machines, especially out-of-order issue pro- cessors. It also requires significant changes to be made to each optimization in a compiler. Triantafyllis et al. [29] develop an alternative approach to reduce the total number of evaluations of a new program. Here the space of compiler options is examined off-line on a per function basis and the best performing ones are clas- sified into a small tree of compiler options. When compil- ing a new program, the tree is searched by compiling and executing the best path in the tree. As long as the best se- quences can be categorized into a small tree, this proves to be a highly effective technique. Pan et al. [22] develop an algorithm called combined elimination which selectively turns off optimizations until the best performance is found for a new application. This al- gorithm was compared to other algorithms for tuning com- piler settings [14, 29] and was shown to achieve the same or better performance as these algorithms while dramatically reducing the tuning time. In a recent paper [23], they parti- tion a program into tuning sections and then use combined elimination to find the best combination of optimizations for each of these tuning sections. By using rating methods, the authors can evalute several different optimization set - tings for a tuning section during one run of the program. They are able to reduce the time to find good optimization settings from hours to minutes. However, the techniques of partitioning a program and rating methods are orthogonal to the particular search algorithm used, therefore we could as well use our models to find good sequences even faster. Yotovet al. [32] describe a model-based approach to op- timize BLAS libraries that can is effective as empirical eval- uation. In a later paper [33], they refine analytical models based on the results of the empirical search for the ATLAS library. A local neighborhood search around the best found points is used to further improve the solutions and perform comparable to the ATLAS global search strategy. However, the analytical models require manual tuning and are com- plicated to design. Cooper et al. [8] use genetic algorithms to solve the compilation phase-ordering problem. They were concerned with finding “good” compiler optimization sequences that reduced code size. Their technique was successful at reduc- ing code size by as much as 40%. Unfortunately, their tech- nique is application-specific. That is, a genetic algorithm has to retrain for each program to decide the best optimiza- tion sequence for that program. Several researchers have also looked at using machine learning to construct heuristics that control a single opti - mization. Stephenson et al. [27] used genetic program- ming (GP) to tune heuristic priority functions for three com- piler optimizations: hyperblock selection, register allo ca- tion, and data prefetching within the Trimaran’s IMPACT compiler. For two optimizations, hyperblock selection and data prefetching, they achieved significant improvements. However, a closer look at the results indicate that all the improvement was obtained from the initial population indi- cating that these two pre-existing heuristics were not well tuned. For the third optimization, register allocation, th ey were able to achieve on average only a 2% increase over the manually tuned heuristic. Cavazos et al. [5] describe an idea of using supervised learning to control whether or not to apply instruction scheduling. They induced heuristics that used features of a basic block to predict whether scheduling would benefit that block or not. Using the induced heuristic, they were able to reduce scheduling effort by as much as 75% while still retaining the effectiveness of scheduling all blocks. Monsifrot et al. [20] use a classifier based on decision tree learning to determine which loops to unroll. They looked at the performance of compiling Fortran programs from the SPEC benchmark suite using g77 for two different architectures, an UltraSPARC and an IA64. They showed an improvement over the hand-tuned heuristic of 3% and 2.7% over g77’s unrolling strategy on the IA64 and Ultra- SPARC, respectively. These results highlight the diminishing results obtained when only controlling a single optimization and highlight the need to control the application of multiple compiler op- timizations. Recently, Cavazos et al. [6] describe using static code features and supervised learning to control several opti- mizations to apply during method compilation in a JIT com- piler. Since Java methods are typically small, static code features were successfully used to characterizing them. In future work, we will compare static versus dynamic fea- tures to predict which optimizations to apply to local code segments. 7 Conclusions In this paper we address the problem of predicting good compiler optimizations by using performance counters to automatically generate compiler heuristics. We do this by using machine learning techniques that predict good code transformations to apply given a program’s performance counter features. Our technique automates the tuning pro- cess and eliminates the need for manual experimentation. Additionally, the heuristics induced by these techniques can generalize to programs that have not been seen before. Us- ing performance counters allows us to apply transforma- tions that will benefit the program being compiled while avoiding optimizations that will degrade performance. Us- ing our models, we can achieve a 10% average speedup over the highest optimization setting in the PathScale compiler on SPEC benchmarks on a recent AMD Athlon much faster than the current state-of-the-art pure search techniques. References [1] F. Agakov, E. Bonilla, J. Cavazos, B. Franke, G. Fursin, M. OBoyle, J. Thomson, M. Toussaint, and C. Williams. Using machine learning to focus iterative optimization. In Proceedings of the International Symposium on Code Generation and Optimization, pages 295–305, 2006. [2] AMD. Compiler usage guidelines for 64-bit operating systems on amd64 platforms. http://www.amd.com/us- en/assets/content type/white papers and tech docs/32035.pdf, 2006. [3] R. Azimi, M. Stumm, and R. W. Wisniewski. Online performance analysis by statistical sampling of microprocessor performance counters. In ICS ’05: Proceedings of the 19th annual international conference on Supercomputing, pages 101–110, New York, NY , USA, 2005. ACM Press. [4] C. M. Bishop. Neural Networks for Pattern Recognition. Oxford University Press, Oxford, UK, 1996. [5] J. Cavazos and J. E. B. Moss. Inducing heuristics to decid e whether to schedule. In Proceedings of the ACM SIGPLAN ’04 Conference on Programming Language Design and Implementation, pages 183–194, Washington, D.C., June 2004. ACM Press. [6] J. Cavazos and M. O’Boyle. Method-specific dynamic compilation using logistic regression. In Proceedings of the ACM SIGPLAN ’06 Conference on Object Oriented Programming, Systems, Languages, and Applications, Portland, Or., October 2006. ACM Press. [7] K. D. Cooper, A. Grosul, T. J. Harvey, S. Reeves, D. Subramanian, L. Torczon, and T. Waterman. Acme: adaptive compilation made efficient. In Proceedings of the 2005 ACM SIGPLAN/SIGBED Conference on Languages, Compilers, and Tools for Embedded Systems, pages 69–77, New York, NY , USA, 2005. ACM Press. [8] K. D. Cooper, P. J. Schielke, and D. Subramanian. Optimizing for reduced code space using genetic algorithms. In Workshop on Languages, Compilers, and Tools for Embedded Systems, pages 1–9, Atlanta, Georgia, July 1999. ACM Press. [9] K. D. Cooper, D. Subramanian, and L. Torczon. Adaptive optimizing compilers for the 21st century. Journal of Supercomputing, 23(1):7–22, August 2002. [10] J. Dean, J. E. Hicks, C. A. Waldspurger, W. E. Weihl, and G. Z. Chrysos. Profileme : Hardware support for instruction-level profiling on out-of-order processors. In International Symposium on Microarchitecture, pages 292–302, 1997. [11] B. Franke, M. O’Boyle, J. Thomson, and G. Fursin. Probabilistic source-level optimisation of embedded programs. In Proceedings of the 2005 ACM SIGPLAN/SIGBED Conference on Languages, Compilers, and Tools for Embedded Systems, pages 78–86, New York, NY , USA, 2005. ACM Press. [12] M. Frigo and S. G. Johnson. The design and implementation of FFTW3. Proceedings of the IEEE, 93(2):216–231, 2005. special issue on ”Program Generation, Optimization, and Platform Adaptation”. [13] M. R. Guthaus, J. S. Ringenberg, D. Ernst, T. M. Austin, T. Mudge, and R. B. Brown. Mibench: A free, commercially representative embedded benchmark suite. In IEEE 4th Annual Workshop on Workload Characterization, Austin, TX, December 2001. [14] M. Haneda, P. M. W. Knijnenburg, and H. A. G. Wijshoff. Automatic selection of compiler options using non-parametric inferential statistics. In Proceedings of the International Conference on Parallel Architectures and Compilation Techniques, pages 123–132, Washington, DC, USA, 2005. IEEE Computer Society. [15] T. Kisuki, P. M. W. Knijnenburg, and M. F. P. O’Boyle. Combined selection of tile sizes and unroll factors using iterative compilation. In Proceedings of the International Conference on Parallel Architectures and Compilation Techniques, page 237, Washington, DC, USA, 2000. IEEE Computer Society. [16] P. Kulkarni, S. Hines, J. Hiser, D. Whalley, J. Davidson, and D. Jones. Fast searches for effective optimization phase sequences. In Proceedings of the ACM SIGPLAN ’04 Conference on Programming Language Design and Implementation, pages 171–182, New York, NY , USA, 2004. ACM Press. [17] P. A. Kulkarni, D. B. Whalley, G. S. Tyson, and J. W. Davidson. Exhaustive optimization phase order space exploration. In Proceedings of the International Symposium on Code Generation and Optimization, pages 306–318, Washington, DC, USA, 2006. IEEE Computer Society. [18] P. S. Ltd. http://www.polyhedron.com, 2006. [19] R. J. McEliece. The Theory of Information and Coding. Addison-Wesley, 1977. [20] A. Monsifrot, F. Bodin, and R. Quiniou. A machine learning approach to automatic production of compiler heuristics. In AIMSA ’02: Proceedings of the 10th International Conference on Artificial Intelligence: Methodology, Systems, and Applications, pages 41–50. Springer-Verlag, 2002. [21] P. Mucci. Papi – the performance application programmi ng interface. http://icl.cs.utk.edu/papi/index.html, 2000. [22] Z. Pan and R. Eigenmann. Fast and effective orchestrati on of compiler optimizations for automatic performance tuning. In Proceedings of the International Symposium on Code Generation and Optimization, pages 319–332, 2006. [23] Z. Pan and R. Eigenmann. Fast automatic procedure-leve l performance tuning. In Proceedings of the International Conference on Parallel Architectures and Compilation Techniques, Seattle, WA, September 2006. IEEE Computer Society. [24] D. Parello, O. Temam, A. Cohen, and J.-M. Verdun. Towards a systematic, pragmatic and architecture-aware program optimization process for complex processors. In SC ’04: Proceedings of the 2004 ACM/IEEE conference on Supercomputing, page 15, Washington, DC, USA, 2004. IEEE Computer Society. [25] I. PathScale. http://www.pathscale.com, 2006. [26] M. Puschel, J. Moura, J. Johnson, D. Padua, M. Veloso, B. Singer, J. Xiong, F. Franchetti, A. Gacic, Y . V oronenko, K. Chen, R. W. Johnson, and N. Rizzolo. Spiral: Code generation for dsp transforms. Proceedings of the IEEE, 93(2):232–275, 2005. special issue on ”Program Generation, Optimization, and Platform Adaptation”. [27] M. Stephenson, S. Amarasinghe, M. Martin, and U.-M. O’Reilly. Meta optimization: Improving compiler heuristics with machine learning. In Proceedings of the ACM SIGPLAN ’03 Conference on Programming Language Design and Implementation, pages 77–90, San Diego, Ca, June 2003. ACM Press. [28] M. Stephenson and S. P. Amarasinghe. Predicting unroll factors using supervised classification. In Proceedings of the International Symposium on Code Generation and Optimization, pages 123–134, 2005. [29] S. Triantafyllis, M. Vachharajani, N. Vachharajani, and D. I. August. Compiler optimization-space exploration. In Proceedings of the International Symposium on Code Generation and Optimization, pages 204–215, Washington, DC, USA, 2003. IEEE Computer Society. [30] R. Vuduc, J. W. Demmel, and J. A. Bilmes. Statistical models for empirical search-based performance tuning. Int. J. High Perform. Comput. Appl., 18(1):65–94, 2004. [31] R. C. Whaley and J. J. Dongarra. Automatically tuned linear algebra software. In SC ’98: Proceedings of the 1998 ACM/IEEE conference on Supercomputing, pages 1–27, Washington, DC, USA, 1998. IEEE Computer Society. [32] K. Yotov, D. Padua, K. Pingali, P. Stodghill, and P. Wu. A comparison of empirical and model-driven optimization. In Proceedings of the ACM SIGPLAN ’03 Conference on Programming Language Design and Implementation, pages 63–76, San Diego, Ca, June 2003. ACM Press. [33] K. Yotov, K. Pingali, and P. Stodghill. Think globally, search locally. In ICS ’05: Proceedings of the 19th annual international conference on Supercomputing, pages 141–150, New York, NY , USA, 2005. ACM Press. [34] M. Zhao, B. R. Childers, and M. L. Soffa. A model-based framework: an approach for profit-driven optimization. In Proceedings of the International Symposium on Code Generation and Optimization, pages 317–327, 2005. A Flexible Approach to Autotuning Multi-Pass Machine Learning Compilers Phitchaya Mangpo Phothilimthana, Amit Sabne, Nikhil Sarda, Karthik Srinivasa Murthy, Y anqi Zhou, Christof Angermueller, Mike Burrows, Sudip Roy, Ketan Mandke, Rezsa Farahani, Y u Emma Wang, Berkin Ilbeyi, Blake Hechtman, Bjarke Roune, Shen Wang, Y uanzhong Xu, and Samuel J. Kaufman∗ Google, ∗University of Washington Email: mangpo@google.com Abstract—Search-based techniques have been demonstrated effective in solving complex optimization problems that arise in domain-specific compilers for machine learning (ML). Unfortu- nately, deploying such techniques in production compilers is im- peded by two limitations. First, prior works require factorization of a computation graph into smaller subgraphs over which search is applied. This decomposition is not only non-trivial but also significantly limits the scope of optimization. Second, prior works require search to be applied in a single stage in the compilation flow, which does not fit with the multi-stage layered architecture of most production ML compilers. This paper presents XTAT, an autotuner for production ML compilers that can tune both graph-level and subgraph-level optimizations across multiple compilation stages. XTAT applies XTAT-M, a flexible search methodology that defines a search formulation for joint optimizations by accurately modeling the interactions between different compiler passes. XTAT tunes tensor layouts, operator fusion decisions, tile sizes, and code generation parameters in XLA, a production ML compiler, using various search strategies. In an evaluation across 150 ML training and inference models on Tensor Processing Units (TPUs) at Google, XTAT offers up to 2.4 × and an average 5% execution time speedup over the heavily-optimized XLA compiler . Keywords-compiler, autotuning, machine learning I. I NTRODUCTION Machine learning (ML) compilers solve multiple optimiza- tion problems to translate an ML program, typically repre- sented as a tensor computation graph, to an efficient executable for a hardware target. Recent works have demonstrated that search-based techniques can be used to solve many of these problems effectively [1]–[10]. However, production ML com- pilers (e.g., XLA [11] and Glow [12]) still rely on heuristics to solve these problems quickly, albeit often sub-optimally. Current search-based techniques [1]–[10] have at least one of the two key shortcomings that prevent them from being deployed in production ML compilers. First, they rely on the assumption that performance-critical optimization decisions are localized within a subgraph and hence can be made independently from the rest of the graph [1]–[8]. This is often not the case. For example, decisions to fuse1 tensor operations affect memory requirements, which 1When operators are fused, intermediate tensors can be used by the consuming operator directly without saving them to the slow main memory. in turn affect decisions to rematerialize2 tensors in different portions of the graph. Furthermore, the subgraph-focused solu- tions assume that they can easily partition a tensor computation graph into suitable subgraphs. However, finding an optimal partitioning for a particular optimization task is a non-trivial combinatorial optimization problem by itself. A common strategy is to partition a graph according to the neural network layers [3], [5], ignoring cross-layer optimization opportunities. We empirically observed a regression of up to 2.6× and 32% on average across 150 ML models by limiting fusions in XLA to be within layers. Furthermore, prior approaches [1]–[10] have primarily studied inference graphs. Training graphs, on the other hand, can be up to two orders of magnitude larger than inference graphs in terms of number of nodes, rendering subgraph decomposition less effective. Second, the optimizations enabled in prior works [1]– [10] are applied at the same stage in the compilation flow, specifically in the loop transformation stage. However, this is impractical in production compilers because compiler transfor- mations are organized as passes to reduce complexity, and have strict ordering constraints. For example, in the XLA compiler, tensor layout assignment occurs before operator fusion. This is required because operator fusion’s goal is to reduce memory traffic, which is impossible to estimate without layouts. The automatic cross-replica sharding [13] happens between the layout and fusion passes. It requires layouts to calculate parallelization overheads correctly, and must execute before the fusion pass because otherwise the distribution granularity becomes coarse, lowering performance gains. Therefore, joint optimization of layout and fusion cannot occur at the same compilation stage. To perform joint layout-fusion optimization using the previous research approaches, all intermediate trans- formations must be co-optimized too, which does not scale in practice. We next discuss our approach to overcome these short- comings. To address the issue of the optimization scope, we develop an autotuner for ML compilers that supports tuning decisions made at both whole graph and subgraph levels. Specifically, we implement XTAT (pronounced “stat”), an autotuner for the XLA compiler.XTAT can tune tensor layouts 2Rematerialization reduces memory usage by recomputing a tensor when it is needed instead of saving it in memory. 1 2021 30th International Conference on Parallel Architectures and Compilation Techniques (PACT) 978-1-6654-4278-7/21/$31.00 ©2021 IEEE DOI 10.1109/PACT52795.2021.00008 6HDUFK&RQ )RUPXODWLRQ RI6LPXODWHG $QQHDOLQJRU (YROXWLRQDU\ 6HDUFK ;7$7 (YDOXDWRU /&0 +DUGZDUH &RQILJ &RVW *UDSK([WUDFWRU ;/$ /RZOHYHO&RGH *HQHUDWRU 7HQVRU)ORZ 3\7RUFK 3URJUDP 738 *UDSKOHYHO 2SWLPL]DWLRQV /D\RXW$VVLJQPHQW 2SHUDWRU)XVLRQ &URVV5HSOLFD 6KDUGLQJ 5HPDWHULDOL]DWLRQ $OJHEUDLF 6LPSOLILFDWLRQHWF .HUQHOOHYHO 2SWLPL]DWLRQV 7LOLQJ9HFWRUL]DWLRQ )ODJVHWF ;7$7 RSWLPL]DWLRQ JUDSK FRQILJ %HVW &RQILJ 7XQH &RPSLOHU (YDOXDWRU +DUGZDUH &RVW0RGHO VHDUFKVSDFH GHIDXOWFRQILJ RXWSXWJUDSK JUDSK FRQILJ FRVW ;7$70EDVHG IRUPXODWLRQRIVHDUFK VFKHGXOHDQGVHDUFK VWUDWHJ\ ;7$70EDVHG IRUPXODWLRQRIWKH FRQILJXUDWLRQVIRU FRPSLOHURSWLPL]DWLRQV Fig. 1: Overview ofXTAT, an autotuner for XLA.XTAT takes as inputs: (a) a program/graph to optimize, (b) a formulation of the search strategy inXTAT-M, and (c) a formulation of the compiler optimization configurations inXTAT-M. XTAT currently supports tuning optimization passes highlighted in red.XTAT uses the learned cost model and/or hardware to evaluate the performance of different optimization configurations and outputs the best configuration found. and fusion decisions at the graph level, and tune tile sizes3 and critical code generation parameters at the kernel (subgraph) level for TPUs [14], [15]. Employing search at the graph level is challenging due to search spaces that are exponentially large in the number of nodes. Therefore, it is important to ensure that the search space for an optimization pass is well designed, as the design can greatly affect the quality of the final solution found by a search method. To this end, we present effective search spaces for optimizations tuned byXTAT. To tune multiple compiler optimizations at different stages, we develop a flexible methodology to apply search to multiple compiler passes, called XTAT-M. The complexity of multi- stage joint optimizations tuning comes from the fact that decisions made in one optimization pass affect input graphs to subsequent passes and, thereby, their configurations and search spaces. To address this complexity,XTAT-M defines configuration-update specifications, which co-relate the state of the intermediate graph left behind by one compiler op- timization to a partial solution for a subsequent compiler optimization. Through such specifications, XTAT-M allows composing search-based strategies in certain passes (e.g., for layout and fusion) with existing heuristic-based strategies in intermediate passes (e.g., for cross-replica sharding). Addi- tionally, XTAT-M enables flexibility to trade off time spent searching for a solution and solution optimality through a configurable search schedule. This flexibility is critical to achieve the best performance given a time budget. Lastly, XTAT-M allows us to apply a wide range of search techniques including exhaustive search, simulated annealing, evolutionary search, model-based optimization, and reinforcement learning. To summarize this paper’s contributions: • We developXTAT-M, a novel methodology to formulate search for multiple optimizations at different stages of an ML compiler with a flexible search schedule. • We build theXTAT autotuner based onXTAT-M to tune tensor layouts, operator fusion decisions, tile sizes, and 3A tile of tensor is processed at a time to effectively utilize fast memory (e.g., scratchpad and cache). code generation parameters in XLA, as shown in Fig. 1. • XTAT is the first autotuner that can jointly tune multiple optimizations at different stages of an ML compiler. • XTAT handles much larger search spaces compared to prior works since XTAT optimizes at both graph and subgraph levels. For instance, the number of valid fusion configurations alone for the EfficientNet training model with approximately 40,000 nodes is 240,000. In contrast, prior works [1]–[8] tune one subgraph, which typically has fewer than 10 nodes, at a time. • We demonstrate how to incorporate advanced techniques such as a learned cost model and various search strategies into XTAT to reduce autotuning time. • We evaluateXTAT on 150 ML models (comprising both training and inference models from Google’s production and research workloads) on TPUs and achieve significant improvement: up to 2.4× speedup and 5% on average over the heavily-optimized XLA compiler. II. XTAT-M:M ETHODOLOGY &F ORMULA TIONS A. Overview We define a configuration on a graph for an optimization pass as a collection of per-node configurations that control how the pass transforms each node in the graph. For example, con- sider the pass that determines a tensor layout (i.e., a physical ordering of tensor dimensions in memory). A configuration for this pass is a collection of physical layouts assigned to tensors at each node in the graph. Searching for the best configuration for a compiler opti- mization involves (i) exploration of candidate configurations, (ii) application of the optimization pass according to the candidates, and (iii) evaluation of the output graphs. Imple- menting these steps for a single optimization is relatively straightforward, while the quality of results depends on the expressiveness and compactness of the search space as well as the capability of the search technique. However, searching for optimal configurations for multi- ple optimizations requires that the search satisfies a critical 2 condition: the search space and the configuration chosen for an optimization pass must be consistent with decisions made in prior passes. For example, consider Fig. 2 with two opti- mization passes,layout assignment(which determines tensor layouts) and operator fusion (which fuses several operators together). Since the performance of a fused node depends on the layouts of the relevant tensors, the decisions in the fusion pass must take into account the layouts decided in the prior pass. Further, the search space for the fusion pass (i.e., the set of node configurations to consider for search) depends on the layout assignment since the layout pass may transform the graph. As shown in Fig. 2, two layout configurations lead to different input graphs for the fusion pass: one contains acopy node, while the other does not; as a result, the fusion search space for the left graph must contain configurations forcopy, but the search space for the right must not. How can we orchestrate searches for joint optimizations to satisfy the above condition? To do so, we identify two key properties that a search should implement. To describe these properties, consider the scenario where an optimization pass, say A, is applied before another optimization pass, sayB. 1) The ordering between the produced graphs is g A(configA) −−−−−−→ g′ B(configB) −−−−−−→ g′′. This ordering implies that: (i) the graphg′ is a result of applying a candidate configuration configA selected for A and (ii) the search space of candidate configurations and a selected candidate configB for B is based ong′. 2) All configurations are well-formed; a configuration configB contains valid configurations for all configurable nodes in g′. Further, when configA is changed, causing graph g′ to change, configB must be updated to be compatible with g′ using the best nodes’ configurations observed so far forB. This ensures that the search forB does not begin the exploration from scratch. To realize this orchestration, we develop a generic method- ology XTAT-M to formulate the interactions between multi- stage compiler optimizations, and search strategies. Our pro- posed search methodology is applicable to compilers that apply multiple optimization passes in sequence. B. Methodology The search formulation ofXTAT-M is displayed in Fig. 3. We model the search process as a sequence of search steps. Each search step takes a set of current candidates C and produces a new set of candidatesC′for the next round. When tuning n optimizations, a candidatec in C captures n graphs (c.graphs) andn configurations (c.configs), wherec.graphs[id] and c.configs[id] are an input graph and a configuration for an optimization pass id respectively. As color coded in Fig. 3, XTAT-M allows one to configure its routines to implement a desired search schedule (red) and search strategy (green), and tailor the configuration-update procedures to specific op- timizations (purple). Each search step (SearchSteplines 8–16) performs the following actions: Ôôô ͞ʾ̶ˀ̶ʽ˂͟ ŎøŒđÔŋø ͞ʽʾ˄͟ îIJĬű ͞ʾ̶˄͟ īÔŷ ͞ˀ̶ʽ˂̶˄͟ ͟͞ ͜ʼ͝ ̶˄͟ ͜ʼ̶ʽ͝ ͜ʽ̶ʼ͝ ͜ʼ̶ʽ̶ʾ͝ ͜ʽ̶ʼ̶ʾ͝ ͜ʼ̶ʾ̶ʽ͝ ͜ʾ̶ʼ̶ʽ͝ ͜ʾ̶ʽ̶ʼ͝ ͜ʽ̶ʼ̶ʾ͝ ͜ʼ̶ʾ̶ʽ͝ Ôôô ͞ʾ̶ˀ̶ʽ˂͟͜ʽ̶ʼ̶ʾ͝ ŎøŒđÔŋø ͞ʽʾ˄͟͜ʼ͝ îIJĬű ͞ʾ̶˄͟͜ʽ̶ʼ͝ īÔŷ ͞ˀ̶ʽ˂̶˄͟͜ʼ̶ʾ̶ʽ͝ îIJŋŸ ͞ʾ̶ˀ̶ʽ˂͟͜ʼ̶ʽ̶ʾ͝ ʽ̶ʼ̶ʾ͝ ʽ ʼ ʼ TÔŸIJŞř ŒŒĔČĬīøĬř aŋøŎÔřIJŎ ;ŞŒĔIJĬ Ôôô ͞ʾ̶ˀ̶ʽ˂͟ ŎøŒđÔŋø ͞ʽʾ˄͟ îIJĬű ͞ʾ̶˄͟ īÔŷ ͞ˀ̶ʽ˂̶˄͟ ͟͞ ͜ʼ͝ ̶͟ ͜ʼ̶ʽ͝ ͜ʽ̶ʼ͝ ͜ʼ̶ʽ̶ʾ͝ ͜ʽ̶ʼ̶ʾ͝ ͜ʼ̶ʾ̶ʽ͝ ͜ʾ̶ʼ̶ʽ͝ ͜ʾ̶ʽ̶ʼ͝ ͜ʽ̶ʼ̶ʾ͝ ͜ʼ̶ʾ̶ʽ͝ Ôôô ͞ʾ̶ˀ̶ʽ˂͟͜ʽ̶ʼ̶ʾ͝ ŎøŒđÔŋø ͞ʽʾ˄͟͜ʼ͝ îIJĬű ͞ʾ̶˄͟͜ʽ̶ʼ͝ īÔŷ ͞ˀ̶ʽ˂̶˄͟͜ʼ̶ʾ̶ʽ͝ ͟͜ʽ̶ʼ ʽ ˄͟͜ʼ̶ʾ ʼ Ôôô ŎøŒđÔŋø îIJĬű īÔŷ ÔôôÔôô ŎøŒđÔŋø îIJĬű īÔŷîIJŋŸ Ôôô TÔŸIJŞř ŒŒĔČĬīøĬř aŋøŎÔřIJŎ ;ŞŒĔIJĬ Fig. 2: Layout configurations determine the input graphs to the operator fusion pass. A node is annotated with its output tensor shape[n0,n1,...], where ni is the size of dimensioni. Layout {d0,d1,...} represents minor to major ordering in memory. Applied configurations are highlighted inred, and other valid configurations are highlighted inblue. A layout configuration specifies the layouts of inputs and outputs of influential operators (i.e., convolution and reshape). The compiler propagates layouts from the influential nodes to others. A copy operator is inserted when there is a layout mismatch. A fusion configuration specifies which nodes are fused, where a node with decision value 1 must be fused with all of its consumers. If a node being fused has multiple consumers (e.g.,add), it is duplicated (recomputed).The fusion configuration foraddis the same (fused) between left and right, but the outcomes differ;conv is fused in the right but not in the left scenario.This figure shows operator fusion directly following layout assignment, but other intermediate passes can alter the input to the fusion pass further. • SelectOpt: select an optimization to tune • GenerateCandidates: develop search candidates • FixAndApplyCandidate: fix and apply a candidate • Evaluate: evaluate a candidate • SelectCandidates: select candidates for the next step T erminate(line 3) determines when the search stops, e.g., when all candidates are explored, or a certain number of steps have been performed, or the time limit is reached. The search process also maintains a global ConfStore that captures the best configurations observed for all optimizations. 1) SelectOpt: The flexibility to control thesearch schedule is critical to achieve the best performance given a desired time budget. Tuning optimizations jointly often enables more performance improvement opportunities only if we are able to explore the search space sufficiently. XTAT-M allows users to configure the search schedule by controlling the return values of SelectOpt. To tune one optimization pass, say, B, after another, say A, SelectOpt can return a series of A,A,..., B,B,...,C,C,... across calls. To enable joint op- 3 Global variables: Opts,ConfStore,best_candidate 1: function MAINSEARCH (ginput ) 2: C ←Init(ginput ) 3: while !Terminate() do 4: C = SearchStep(C) 5: end while 6: end function 7: 8: function SEARCH STEP(C) 9: op tid ←SelectOpt(Op ts) 10: C′←GenerateCandidates(op tid ,C) 11: for c : C′ do 12: FixAndApplyCandidate(op tid ,c) 13: Evaluate(c) 14: end for 15: return SelectCandidates(C,C′) 16: end function 17: 18: function FIXANDAPPL YCANDIDA TE(op tid ,c) 19: g ←ApplyOpt............ (op tid ,c.graphs[optid],c.configs[optid]) 20: // Update configs of later passes to be compatible with g 21: for id : SubsequentOpts(Op ts,op tid ) do 22: c.graphs[id] ←g 23: c.configs[id] ←InferConfig(c.configs[id],g,ConfStore[id]) 24: g ←ApplyOpt............ (id,g,c.configs[id]) 25: end for 26: c.graphs[final] ←g 27: end function 28: 29: function EVA L U AT E(c) 30: c.cost ←ExecuteGraph(c.graphs[final]) 31: if c.cost < best_candidate.cost then 32: best_candidate ←c 33: UpdateStore(ConfStore,c.configs) 34: end if 35: end function 36: 37: function INIT(g) 38: for id : Op tsdo 39: con f ig←GetInitConfig................ (id,g) 40: gcombo[id] ←g 41: con f igcombo[id] ←con f ig 42: g ←ApplyOpt............ (id,g,con f ig) 43: end for 44: gcombo[ f inal] ←g 45: cost ←ExecuteGraph(g) 46: C[0] ←{graphs : gcombo,configs: configcombo,cost : cost} 47: return C 48: end function Fig. 3: Formulation of XTAT-M search methodology. Routines in red are configured by users to control the search schedule. Routines in greenare implemented by search strategies. Routines in purpleare optimization-specific and essential for joint optimizations....................Routines in blueare interfaces to retrieve information from a compiler. timizations, we can configure SelectOpt to alternate passes: A,B,C,A,B,C,.... XTAT-M also supports a mixture of sequen- tial and joint tuning, e.g., tuningA and B jointly followed by tuning C and D jointly: A,B,A,B,...,C,D,C,D,.... Note that a mixed search schedule alone does not enable a joint optimiza- tion, it is the combination of a mixed search schedule and candidates fixing (described later in FixAndApplyCandidate) that enables a joint optimization. 2) GenerateCandidates: XTAT-M lets one apply various search strategies by implementingGenerateCandidates, which generates a new set of candidates from the current set of candidates. Note that a candidate contains configurations for all optimizations being tuned.GenerateCandidatesprimarily focuses on generating new configurations for a specific opti- mization op tid, and optionally new configurations for the sub- sequent interacting optimizations. Note that a new candidate created from this routine may be ill-formed; i.e., c.configs may not be compatible with c.graphs because this routine changes configurations without updating or considering the graphs. Consider Fig. 2 as an example, let the left layout and fusion configurations compose a candidatec. If we mutate only the layout ofc to be the layout shown on the right side of the figure, the fusion configuration is no longer valid for the right graph because thecopynode has been removed. We allow GenerateCandidatesto generate ill-formed candidates in this step and then fix them in the next step. This is how we enable search strategy implementers to develop their search algorithms without having to deal with complex compiler transformation effects between interacting optimizations. 3) FixAndApplyCandidate: In this step, we update the intermediate graphs and the configurations of all optimiza- tions to be well-formed using ApplyOpt and InferConfig. ApplyOpt(optid,g,config) transforms g by applying optimiza- tion id and potentially more optimizations (using compiler’s heuristics) betweenid and id +1. For example, whenop tid is layout, to obtain the input graph for the fusion pass, we apply layout assignment pass with respect toconfig and many more transformations such as conditional code motion and cross- replicas sharding. Note that not all of these transformations are worthy of tuning;XTAT-M enables applying the heuristic- based decisions for them naturally. When a configuration for an optimization, say A (e.g., layout), is changed byGenerateCandidates, the configurations for subsequent interacting optimizations, sayB (e.g., fusion), must be updated to be well-formed. InferConfig (line 23) does so by fixing c.configs[B] to be compatible with the graph g, generated from applying c.configs[A] for pass A. InferConfig first identifies the nodes that areunchanged be- tween g and c.configs[B] and carries forward the configurations in c.configs[B] for such nodes. For the other nodes ing, it pulls the best configurations found so far from the globalConfStore if present; otherwise, it generates optimization-specific de- faults using GetInitConfig(B,g)[n]. By default, GetInitConfig returns the default configuration generated by the compiler’s heuristic, but one can override it to return a random con- figuration or others for more exploration. The semantics of InferConfig is shown in theinfer-configrule in Fig. 12 in the appendix. ConfStore[optid][fp(n)] stores the best configuration for op- timization optid for node n with fingerprintfp(n). Two nodes are considered to be the same or unchanged if they have the same fingerprint. This approach of reusing configurations of unchanged nodes assumes that the configurations of these nodes still work well in a new context, provided we can define theunchangedrelation appropriately. A simple strategy is to compare only the nodes’ attributes (e.g., operator type, 4 T ABLE I: Implementations of search-strategy-specific functions inXTAT-M. Column |C| describes the number of candidates returned by the functionSelectCandidates. ParametersM and K in EVO, MBO, and RL are configurable by users. Strategy Function GenerateCandidates Function SelectCandidates |C| Exhaustive Return the next candidate (not visited before). N/A N/A SA Mutate configurations of some nodes in the current candidate. Return either the old or new candidate depend- ing on their costs and the annealing temperature. 1 EVO Generate M new candidates by crossing over parent candidates and mutate some nodes’ configurations. Return the K (where K > M) most recent (unique) candidates, using costs for tie breaking. K MBO Generate M new candidates from the model’s latent state. N/A N/A RL Generate M new candidates from the learned policy at the current state (i.e., the current candidate). Return the best candidate so far. 1 input/output shapes, layouts etc). Fig. 2 shows how this strategy might infer the fusion configuration on the right from the left one. Theadd is identified as unchanged, soadd will be fused with bothreshapeand conv,b u tadd and conv are not fused together in the left scenario. To define unchanged more conservatively, we consider a context around a node by computing a node’s fingerprintfp(n) from both its attributes and its neighborhood withink hops. If k is set to one, only reshape remains unchanged between the middle left and the middle right graphs in Fig. 2, so we will not reuse the configuration foradd. In practice,k is set to five for the fusion pass (from hyperparameter tuning). For a node-level optimization where an optimal configuration for a node is independent from the rest of the graph, we can simply set k = 0 to ignore the neighborhood. 4) Evaluate: This step evaluates the performance of a candidate. If the new best candidate is found, we update the global ConfStore (line 33). The update overwrites a previous configuration for a node with respect to fp(n) if its configuration changes, while retaining configurations for nodes that do not belong to the candidate, as formalized in the update-storerule in Fig. 12 in the appendix. It is important to retain configurations for nodes that do not belong to the candidate because the current best candidate may not be optimal and future search steps taken by the search strategy may favor graphs that contain these nodes. 5) SelectCandidates: The last action is selecting a set of generated candidates to pass to the next round. To support tuning an additional pass, one can simply add the optimization to theOp tslist, configure the search schedule through SelectOpt, set the neighborhood size forfp for that specific optimization (which can be set through hyperpa- rameter tuning), and modify the compiler pass to apply the optimization (ApplyOpt) according to a given configuration. Note that fixing illegal combinations of configurations is the key to our joint autotuning methodology. Simply dropping illegal combinations is insufficient for joint autotuning because changes applied to one pass configuration without the fix are often illegal. This means one has to fall back to using default configurations for later passes, resulting in tuning one pass after another, but not a joint optimization. C. Search Strategies Below, we describe a wide spectrum of search strategies that we have evaluated. Table I summarizes how the following search strategies implement routinesGenerateCandidateand SelectCandidate. 1) Exhaustive search within a node:The exhaustive strat- egy generates a new candidate by selecting the next option for the current node’s configurations. When all configurations have been explored for the current node, it moves on to the next node. This strategy can be used for node (kernel) level optimizations, such as tile size selection. 2) Simulated annealing (SA): SA mutates a candidate and probabilistically accepts a new one based on annealing tem- perature that decreases over time. We have found the following types of mutation operators to be effective: • Single-node: mutates the configuration of one randomly selected node. • Multi-node: mutates configurations of all nodes indepen- dently with probabilityp, wherep decreases as a function of temperature in simulated annealing. • Group: mutate configurations of a randomly-selected set of nodes grouped by a certain criterion. We have empirically observed that a multi-node mutation works well for fusion autotuning and a combination of group and single-node mutations works best for layout autotuning. 3) Regularized evolution (EVO):EVO performs evolution- ary search using a population of K individuals. Each new individual is generated by selecting two parents from the population using binary tournament selection, recombining them with some crossover rateγ, and mutating the recombined individual with some probabilityμ. Following [16], to promote exploration, the population is updated by replacing the oldest individuals by newly evaluated individuals. In our experiment, we use the parametersK = 100, γ = 0.2, andμ = 0.01. We also considered population-based evolutionary optimization using P3BO [17] but did not find clear performance improvement over a single evolution optimizer. 4) Model-based optimization (MBO): MBO performs model-based optimization with automatic model selection [18]. At each optimization round, a set of candidate regression models are fit to the data acquired thus far, and their hyper- parameters are optimized by randomized search and five fold cross-validation. Models with a cross-validation score≥0.4 are ensembled to define an acquisition function. This function is then optimized by regularized evolution to generate a new batch of samples. Candidate models include ridge regression, random forests, gradient boosting, and neural networks. 5 5) Deep reinforcement learning (RL):A deep RL method (GO) [19] is designed specifically for ML compiler’s graph optimizations. GO uses a graph neural network (GNN) to create node embeddings and segmented recurrent attention layers to capture long-range dependencies that appear in a computation graph. The policy network transforms the graph representation into optimization decisions with soft attention. The learning objective is optimized using Proximal Policy Optimization (PPO) [20]. Instead of using conventional RL algorithms, we leverage the existing compiler heuristics by initializing the search with the default heuristic solution, and modify the RL sampling stage to encourage more exploitation. Concretely, we modify the state transition function such that RL only traverses to a state with a higher reward than the default configuration’s:S(t)= S(t −1) if R(t) < R(0), where state S(t) is the embedding of the fusion configuration at step t, and R(0) is the reward for the default configuration. D. Limitations There are some important optimizations, such as graph rewrites, that do not naturally lend to a node-configuration- based representation. In such cases, we believe thatXTAT-M can still be used as a subroutine, where the outer loop applies rewrites, and for each candidate change, we useXTAT-M to optimize other optimization decisions. Notice thatXTAT-M does not have to start the search from scratch every iteration because the global ConfStore persists across all iterations. Our formulation also does not support tuning an unbounded number of passes, for example, passes that run until a fixpoint. III. XTAT:I MPLEMENT A TION INXLA We developXTAT based onXTAT-M to tune tensor layouts, operator fusion decisions, tile sizes, and code generation parameters in XLA.XTAT’s target accelerator is TPUs [15], energy-efficient ML accelerators. A. Background on XLA XLA is a ML compiler capable of generating code for various hardware targets [11]. Its workflow can be split into three stages. In the graph-level passes, XLA uses a graph- based intermediate representation named High-Level Opera- tion (HLO) to describe a tensor computation graph. V arious compiler passes transform HLO so that the output graph is algebraically optimized, and is ready to be mapped onto the target hardware. At the end of the graph-level phase, the optimized HLO graph consists of nodes that represent fusions of multiple operations. We refer to a fused node as akernel. Next is the hardware lowering phase; the compiler converts each individual kernel into instructions that can be executed on the target hardware. In the third phase, low-level architecture- specific optimizations are applied, such as VLIW instruction scheduling, peephole optimizations, and register allocation. B. XTAT’s Optimization-Specific Search F ormulations We instantiate XTAT-M to tune the most performance- critical optimization passes in XLA including layout as- signment, operator fusion, and tile size selection, as well T ABLE II: Instantiation ofXTAT-M for specific optimization passes tuned byXTAT. Optimization Applicable node Node’s con f ig layout assignment conv. & reshape input and output layouts operator fusion fusible node fusion control bit tile size kernel w/ tiling input and output tile sizes flags non-comm kernel lowering-phase flag values as compiler’s flags used during the lowering phase. Layout assignment and operator fusion effect graph-level changes and hence are optimized globally. Tile size and flags selection are kernel-level optimizations and hence are optimized for each kernel independently. Apart from these optimizations, XTAT employs the other heuristic-based passes used in XLA. Our choice of passes to tune was influenced by expert XLA developers who suggested these optimizations as ones that significantly affect performance of most ML models. Note that layout and/or fusion decisions heavily influence other opti- mizations such as cross-replica sharding and rematerialization. While rematerialization and operator scheduling are important for making a program fit in available memory, they do not typically reduce program’s execution time. For each optimization pass we tune, we aim to define a search space that is: (1) expressive, i.e., contain diverse candidates that lead to optimal outcomes; (2)compact, i.e., include only valid candidates, few candidates that have the same behavior, and not too many more bad candidates than good ones. We specializeXTAT-M’s generic formulation to specific optimizations as summarized in Table II. The rest of this section details the search formulation for each optimiza- tion. We also describe existing XLA heuristics and alternative search formulations, which are the baselines in our evaluations. Layout Assignment: The layout assignment pass chooses the physical layouts of the input and output tensors of each node to satisfy constraints from the user’s program, the com- piler backend, and the underlying hardware, while minimizing the program’s execution time. An example layout constraint for convolution on TPUs is that the input and output must have input feature, output feature, or batch dimensions as their most minor dimensions. Figure 2 displays the valid input layouts ofconv in blue. Layout{d0,d1,...} represents minor to major dimensions, where elements in the most minor dimension are physically consecutive. If an edge connects an output to an input with a different layout, the compiler inserts a copy (transpose) operator to convert the layout. In Fig. 2 (left), the compiler assigns layout{1,0,2} to the output of add but {0,1,2} to the first input ofconv, causing a layout mismatch, and the insertion of a copy operator. The compiler must trade-off between selecting the best layouts for each specific operator and the overhead from copy operators. Compiler’s heuristic:XLA performs layout assignment in multiple rounds. Initially, the pass includes only constraints from the program’s inputs and outputs. In each round, the layout propagation algorithm propagates layouts from the constrained operators to others through element-wise, pad, and slice operators. This optimistic propagation may cause layout 6 constraint violations at some operators. After each round, the pass uses various heuristics — ranging from a rough cost model to hard-coded decisions depending on the operators — to rectify the violations. This process continues until all constraints are satisfied. Naïve search formulation:We could define the search space to cover all permutations of the dimensions of input and output tensor of every node. However, this leads to an extremely large search space with many invalid and inefficient candidates. Our search formulation:We define the search to configure only the most layout-performance-critical nodes, which are convolution4 and reshape operations because they are common operations and have the most constrained implementations for TPUs. The search queries the compiler for valid input-output layout combinations for these nodes. Once layouts of reshape and convolution nodes are assigned, we leverage the existing layout propagation algorithm to propagate layouts from these nodes to others. This search space contains only valid and relatively efficient candidates. Operator Fusion: When operators are fused, intermediate tensors can be used by the consuming operator directly without saving them to the slow main memory. Fusion also reduces kernel launch overheads. While most ML compilers [1], [3], [4], [6], [10], [21] support fusions of a limited set of oper- ations, XLA can fuse more complex operations (e.g., gather, scatter, reshape, reduce, etc.) resulting in more optimization opportunities as well as more decisions to make. Typically, when an operator is fused into multiple consumers, it must be duplicated (recomputed) in each consumer because consumers can have different iteration spaces (loop structures). This is illustrated in Fig. 2, whereadd is fused into bothreshape and copy. The compiler must trade between recomputation and reduced memory communication. Compiler’s heuristic:The XLA fusion algorithm maintains a priority queue of all nodes in the graph. A cost model computes the priority of a node as the benefit of fusing that node into its consumers. The algorithm iteratively fuses a node with the highest priority value until all nodes have negative priority values. The fused node and its consumers are removed from the queue, newly formed fused nodes are inserted, and the priority values of affected nodes are updated. Our search formulation:We assign a boolean value to each fusible node to control whether it is fused with its consumers. Alternative formulation (edge):We can assign a control bit per edge (instead of per node) such that a parent node is fused with only a consumer whose edge is marked. However, when a parent node u is fused with a consumer nodev but not a consumer nodew, the compiler saves the intermediate output of u in the slow memory; as a result, we do not get the full benefit of fusion. While this formulation is more expressive than the per-node formulation, we believe this additional coverage is unnecessary. Alternative formulation (node priority):Another approach 4All tensor contraction operations (e.g., multiplication and einsum) are converted into convolutions before layout assignment in XLA. is to assign a node a priority value instead of controlling its fusion behavior explicitly, similar to GO [19]. We can adapt the existing heuristic to use these priorities as its initial node priorities, instead of using the cost model. However, the heuristic dynamically adjusts the priorities when nodes are fused; a configuration cannot define these values in advance because we do not know how many adjustments will occur. A workaround is to set the priority of the newly fused node to the sum of its constituents’ priorities. This search space is larger than ours, but covers the same set of behaviors. Alternative formulation (flags):Another approach is to tune the compiler’s fusion-related flags. We try tuning flags that (1) limit fusions of inputs into convolutions, (2) limit fusions of outputs into convolutions, and (3) parameterize the fusion cost model. This search space is small, and does not grow as the number of nodes increases. However, this approach provides less control than the other formulations. Tile-Size Selection:The goal is to pick an optimal tile size for each kernel’s input and output tensors such that they fit in scratchpad memory. Compiler’s heuristic: XLA enumerates all possible tile sizes and chooses the optimal one according to hand-written analytical cost models. Search formulation:We query the compiler to get a set of valid tile sizes for each kernel to form the search space. The number of tile sizes we autotune ranges from 2 to 500,000. Lowering Flags: Apart from tile size selection, the lowering phase is also responsible for many performance- critical decisions. Many of these decisions are determined by heuristics that are controlled by flags. Some examples include instruction window size for hoisting load/store instructions, enabling overlaps of input/output DMAs, and scratchpad limit to allocate to an operator. Compiler’s heuristic:The compiler developers set these flag values to “magic" numbers that work well on most benchmarks in the regression suite. Search formulation:For an integer flag, we limit the search space to four sensible values.XTAT tunes the total of eight integer and boolean flags. C. XTAT’s Search Schedule We configure SelectOpt in XTAT-M to explore different search schedules for tuning our four target optimizations. For scalability, we choose to decouple graph-level optimizations (layout and fusion) from kernel-level optimizations (tile size and flags) for scalability. 1) Joint layout-fusion autotuning: Following the formu- lation presented in Section II-B, we configure SelectOpt to alternate between layout and fusion everyS steps, whereS is set to five via hyperparameter tuning. Mutating both layout and fusion configurations in one search step performs slightly worse than the alternating strategy. 2) Joint tile-size-flags autotuning: The tile size selection pass does not change the graph, merely annotating nodes with tile sizes, so the joint tile size and flags optimization is less complex. Further, the joint search space of tile sizes and flags 7 is small enough for enumeration. Hence, we performed an exhaustive search within each node on the cross-product of tile size and flags search spaces until the time limit is reached. We also explore tuning tile size and then flags sequentially. We configure SelectOpt to tune tile size until exhaustion before switching to flags. The result in our evaluation (Section IV -B) reveals that tuning them in sequence is superior to tuning them jointly because we can only explore a small fraction of the entire joint search space before timeout. Thus, we configure XTAT to tune tile size and flags separately. D. Execution Time Measurement 1) Measurement on hardware: a) Kernel execution time: Most kernels’ runtimes do not depend on input data, so they can be measured reliably using random inputs; this is an approximation in a few cases such as gather and scatter kernels. We do not tune tile sizes for kernels that communicate across multiple devices; their optimal choices are trivial since there is no complex tradeoff between communication and compute. We parallelize runtime measurements across machines, and use multi-threading to further parallelize compilation. b) Graph execution time: We measure the runtime of a graph by summing its kernels’ runtimes. We ignore kernels that communicate across multiple devices, as layout and fusion decisions rarely affect these kernels’ runtimes, enabling tuning a multi-device model on a single device. We ignore loops and conditionals, considering only the kernels in their bodies. We found these approximations to be accurate enough for ranking in autotuning. One can improve the fidelity of the estimates using program traces to weight kernels’ runtimes by their execution counts. Finally, we ignore interactions between kernels as they do not execute concurrently on a TPU, leaving only negligible effects like code prefetching and device temperature. We use caching to avoid measuring identical kernels repeatedly since small configuration changes leave most kernels in a graph unchanged. 2) Learned cost model:To avoid expensive candidate eval- uations (compiling and executing on real hardware), we train a learned cost model to predict execution time, following the TPU learned performance model [22]. The model uses a GNN to encode operation features and the structure of a kernel subgraph. Node embeddings outputted from the GNN are summarized using a simple reduction function to generate a kernel embedding, which is fed into a feed-forward layer to produce a final prediction. We train one model for all graph- level optimization tasks, one for tile-size selection, and one for flags selection. The GNN is shared between tile-size and flags models. For graph-level tasks, the model predicts the absolute runtime of a kernel based on the default tile size and flag values, selected by the compiler’s heuristics. The entire program’s runtime is the summation of the kernels’ predictions. For kernel-level optimizations, the model predicts relative runtimes of different configurations of a given kernel. To ensure accuracy of the model for newer types of work- loads and to keep up with compiler’s changes, we finetune the model periodically; we freeze the GNN layers and retrain only the feed-forward head. Since the model can never be 100% accurate, we execute the topk configurations on real hardware and pick the best. IV . EV ALUA TIONS Our benchmarks comprise 150 machine learning models from the XLA TPU regression suite representing both produc- tion and research usage at Google. They include both inference and training graphs, with sizes ranging from 100 to 56,000 nodes. We report execution time speedup of each benchmark over itsdefault execution time when compiled using the XLA compiler’s heuristics, which have been continuously improved by a large team of experts since 2016 for production usage. Execution time is measured on TPU v3 [15]. A. End-to-End Autotuning 1) Tuning on real hardware:According to the results from Section IV -B, we set our end-to-end autotuning schedule as follows: first, jointly tune layout and fusion via SA, followed by exhaustive search for tile-size autotuning, and ending with exhaustive search for flags tuning. The joint layout-fusion optimization was tuned for two hours on 10 TPU machines (each with a host and an accelerator) or at most 10,000 candidate evaluations on each machine for each model. The exhaustive search for tile-size and flags autotuning is sharded to run on 10 machines with one hour timeout for each task. The results in this section show whatXTAT can achieve given a moderate amount of resources and time; techniques to reduce tuning time and resources will be evaluated later. Figure 4 reports the real execution time speedup using representative program inputs and complete control flow. The figure breaks down the speedup contributions from autotuning different passes. We display 43 models that achieve perfor- mance improvement of 5% or more. Overall,XTAT offers 5% speedup on average over the production compiler across 150 models, where tile size and fusion autotuning contributes the most to the total speedup, followed by layout, and flags auto- tuning. We see a huge speedup on A VSpeech inference (2.4×) and Translate Transformer inference (1.5×). Nine models also exhibit more than 15% improvement. Note that the XLA compiler has been heavily optimized for most of these models; nevertheless, the autotuner still provides substantial speedup: 14% on MLPerf DLRM training (recommendation model), 13% on MLPerf Mask RCNN training, 11% on MLPerf SSD training, and 7% on a few ResNet training models. 2) Tuning with learned cost model: Next, we evaluate the learned cost model in terms of its efficacy on reducing tuning time. We generated training data for the learned cost model from compiling and running the 150 ML models using random layout, fusion, tile size, and flag configurations. Eight benchmarks were held out for testing. On the hold-out benchmarks, we compared: (1) using only real hardware for evaluations and (2) using the learned cost model to select topk configurations to evaluate on real hard- ware. Both settings employed the same autotuning schedule 8 6SHHGXS     DYVSHHFKBL WUDQVODWHBWU PDJHQWDBG WWVBQDWBV\QW WUDQVODWHBWU JUDSKQHWVB JUDSKQHWVB XQHWG RSHQDLBYB POSHUIBGOUP POSHUIBPDV JUDSKQHWVB POSHUIBVVG XQHWBWUDLQLQ HIILFLHQWQHW POSHUIBPDV PQDVQHWBD PQDVQHWBE PDVNBUFQQ EDEHOILVKBWW RSHQDLBYB WUDQVODWHBK UHVQHWBYB WHQVRUWHQV UHVQHWBYB WWVBV\QWKHVL KDORQHW S\WRUFKBWSX WXQDVBVLPS XQHWGBVSD GOUPBVKDP LQFHSWLRQBY GOUPB[BZL GOUPBGHQVH PDVNBUFQQ DOH[QHWBWUDL JDPHSOD\B GHQVHBVXE LPDJHBHPE POSHUIBVVG UHVQHWBPRG GOUPBGHQVH WUDQVODWHBK )ODJV 7LOH6L]H )XVLRQ /D\RXW Fig. 4: End-to-end model speedups from autotuning 150 ML models. The figure shows only models that achieve 5% or more improvement. The first bar (A VSpeech inference) has 2.36× speedup (2.34× from fusion and 2% from tile size). There is no performance regression on the rest of the benchmarks; in the worst case, the model’s execution time remains the same. (joint layout fusion, followed by tile size, and ended with flags tuning). For (1), we used the same autotuning setup as in Section IV -A. For (2), we also used 10 TPU machines to perform real evaluations on hardware but used 10 CPU machines at the beginning to select top layout and fusion configurations in order to cut down time using TPU machines, which are in high demand. In particular, we first ran the joint fusion-layout autotuning on 10 CPU machines for two hours or at most 10,000 steps using the learned cost model, selected the top (k = 10) candidates from each machine, and ran them on 10 TPU machines. Then, we used the learned cost model to pick the best (k = 5) tile sizes and flags from each shard to execute on a TPU. Here, we ran both cost model evaluations and real hardware evaluations on TPU machines as time spent on cost model evaluations are negligible. Figure 5a reports the execution time speedup using represen- tative program inputs and complete control flow, and Fig. 5b reports the tuning time. Overall, using the learned cost model achieves almost the same speedup as using real hardware alone, while drastically reducing tuning time. On average, it reduces the tuning time of tile sizes and flags by 6 × and 8× respectively. Notice that although it does not help reduce the total layout-fusion tuning time significantly, it reduces the tuning time on TPU machines by 240×. This improved tuning time makes it possible to run the autotuner at scale. We have deployed the tile size and flags autotuning to automatically optimize the top workloads in Google’s fleet daily. The learned cost model enabledXTAT to tune 20× more kernels per day. In the past 10 days,XTAT has sped up the most heavily-executed kernels by 3.5% and 1.6% on average from tile size and flags tuning respectively. 3) P erformance analysis: The speedup from autotuning generally comes from higher FLOPs utilization. Good tile sizes balance computation and memory bandwidth utilization.XTAT doubles the tile sizes of many copy operations in the Translate Transformer benchmark, increasing the memory bandwidth utilization of these operations from 45% to 70%, resulting in an overall speedup of 1.3×. (a) Execution time speedup on benchmarks in the hold-out set when using the learned cost model vs. using hardware evaluations alone. Higher is better. Using the learned cost model achieves the same speedup of 2.4× on AvSpeech as using the real hardware. (b) Tuning time in minutes (maximum across 10 machines). Lower is better. Light blue is tuning time on CPU machines, which are cheaper and more abundant resources. Fig. 5: End-to-end autotuning: the learned model drastically reduces tuning time while achieving almost the same speedup as using real hardware alone. Fusion autotuning generates better fused operators, enabling more efficient tile sizes for corresponding operations. E.g., in A VSpeech inference, fusion tuning moves one reshape operation out of a convolution fusion operation, enabling it to use a tile size that is 12.5× larger than before. As a result, this convolution fusion is sped up by 12.5× with over 2× 9 FLOPs utilization and over 3×memory bandwidth utilization, resulting in an overall speedup of 2.3× for that benchmark. Good layout assignment generally reduces the overall data- formatting overheads. However, autotuning Translate Trans- former reveals an intricate relationship between different op- timizations. Layout tuning adds a copy operation, removing a bitcast from a long-running fused operation. As a result, the FLOPs and memory bandwidth utilization of the fusion operation increases by over 2× and over 1.5× respectively, yielding an overall speedup of 1.16× for that benchmark. 4) Result discussion: Our performance improvements may at first seem modest. However, our benchmarks are repre- sentative of large, real world deployments, so even small improvements translate to significant resource savings. Further, the baseline compiler we compare against is actively being tuned against the same benchmarks (and sometimes in the light of our own tuning results!), making it a constant battle to stay ahead. WhenXTAT was applied to top workloads from the TPU fleet (beyond the benchmark suite), we saw higher speedups (approximately 15% on average). Prior works [1]–[7], [10] evaluate only on inference models, and show impressive performance improvements. However, their baselines are library kernels (from CuDNN, MKL, etc) that are generally optimized for training workloads. In contrast, our baseline is the XLA TPU compiler, which is optimized for both inference and training workloads. B. Search F ormulations To evaluate the search formulations presented in Sec- tion III-B, we used SA as the search strategy, measured execu- tion time using real hardware, and selected 10 benchmarks that showed significant speedup from autotuning for a particular optimization problem. We ran 10 replicas of SA with random seeds in parallel and reported the best configuration found among all the replicas. On each replica, we ran the search for 10,000 steps with a two-hour time limit. We experimented with two modes: starting the search from a default configuration (from the compiler’s heuristic) and starting from random con- figurations (different replicas starting from different random configurations). This subsection reports speedup with respect to execution time measured as described in Section III-D1 (ignoring control flow and using randomly generated data). 1) How effective is our layout assignment formulation?: As shown in Fig. 6, when starting the search from a default configuration, our proposed search formulation drastically outperforms the naïve formulation, as we hypothesized. When starting from random configurations, the search using the naïve formulation is unable to find any valid layout configuration for any of the benchmarks. In contrast, the search using the proposed formulation is able to find valid configurations for all benchmarks with an average speedup of 8.6%, which is almost the same as the average speedup of 9% when starting from the default configuration. 2) How effective is our operator fusion search formula- tion?: Figure 7 shows the results when starting the search from a default configuration. The per-node control bit formulation 6SHHGXS      UPB[BZLGHBGHQVHDYVSHHFKBWUDLQLQJJUDSKQHWVBQPJUDSKQHWVBQWUDQVODWHBWUDQVIRUP POSHUIBGOUPPOSHUIBVVGPOSHUIBVVGPOSHUIBVVG RSHQDLBYBUQQBQDW JHRPHDQ 3URSRVHG 1DLYH Fig. 6: Layout autotuning: execution time speedup using different search spaces (starting from a default configuration). Our proposed formulation outperforms the naïve formulation. 6SHHGXS     DXWRHQFRGHUHIILFLHQWQHWJUDSKQHWVBQJUDSKQHWVBQJUDSKQHWVBQPQDVQHWBEUHVQHWBSDUDO UHVQHWBYXQHWBWUDLQLQZDYHQHWBWUDL JHRPHDQ 3HU1RGH 3HU(GJH 1RGHSULRLUW\ )ODJV Fig. 7: Fusion autotuning: execution time speedup with differ- ent search spaces (starting from a default configuration). The per-node search space offers the most speedup. is slightly (2 percentage points) better than the per-edge al- ternative, as hypothesized. The difference is more pronounced when starting from random configurations (not shown in the figure), where the per-node formulation’s average speedup is 8 percentage points higher than that of the per-edge formulation. Another search formulation uses node priority, and is sig- nificantly worse than the control bit formulations. Even when starting from default, the best candidates found in this search space are worse than the default; it is impossible to faithfully reconstruct the default configuration in this formulation as priority values change dynamically during the fusion pass. The last alternative search formulation is tuning flags. Because the entire search space has only 52 candidates, we performed an exhaustive search here. As we hypothesized, this formulation is worse than the control bit formulations due to its limited expressivity, offering tiny speedup on all benchmarks. 3) How much benefit does joint layout and fusion autotun- ing offer?: To investigate the potential of joint autotuning of multiple passes, we compared two strategies: tuning layout and then fusion sequentially (each for two hours), and tuning them jointly (for four hours). Figure 8 shows the results for benchmarks where joint autotuning improves over tuning layout and then fusion. For the remaining six benchmarks, sequential and joint tuning offer the same speedup. According 10 6SHHGXS        JUDSKQHWVBQPJUDSKQHWVBQ UHVQHWBY XQHWBWUDLQLQJ /D\RXWWKHQ)XVLRQ -RLQW -RLQW QRUHXVH -RLQW UDQGRPVWDUW -RLQW QRUHXVHUDQGRPVWDUW Fig. 8: Autotuning layout then fusion vs. autotuning them jointly (with/without configuration reuse). The first three in each cluster start from a default configuration; the last two start from random configurations. ‘No reuse’ does not employ the configuration reuse mechanism (the globalConfStore). Joint tuning with the reuse mechanism offers the most speedup. to Fig. 8, joint tuning is better than sequential tuning. This is because a better layout configuration may disable an even better fusion configuration. In addition to evaluating the achievable speedups, we also compared tuning time between sequential tuning and joint tuning. We measured the time taken to reach within 0.1 percentage point of the highest speedup. On average, joint tuning took 2.7× less time than sequential tuning to reach the highest speedup across 10 benchmarks. This is likely because, in some benchmarks, the sequential search schedule wasted time optimizing layouts (in the first half of the search) when there was not much room for improvement. This experiment also suggests that our simple search tech- nique is still effective in an extremely large search space, thanks to our strategy of leveraging compiler heuristics. 4) How important is the configuration reuse mechanism for joint autotuning?: The configuration reuse mechanism (Section II-B3) enables the autotuner to reuse parts of the best fusion configurations found so far when a layout configuration changes. Without this mechanism, the autotuner must reset to a default or random fusion configuration when a new graph is generated by a new layout configuration. According to Fig. 8, when the search starts from a default configuration, there is no difference between using and not using the reuse mechanism. However, if the search starts from a random configuration and GetInitConfig in Fig. 3 returns a random configuration, we observe significant benefit from employing the reuse mechanism: up to 15% execution time improvement. In terms of time to reach the highest speedup (within 0.1 percentage point) when starting from a default configuration, reuse or no reuse mechanism took similar time on all but two benchmarks. On MLPerf DLRM and GraphNets n4k, the reuse mechanism reached the highest speedup 4.5× and 1.8× faster than no reuse mechanism did. Hence, the reuse mechanism is useful for reducing tuning time for some models and essential if one does not have good default configurations. 5) How much benefit does joint tile size and flags autotun- ing offer?: Similar to joint layout-fusion, we compared tuning tile size and then flags, and tuning them jointly. Since tile size and flags search space is small, we enumerated all candidates and evaluated them in a random order up to a time limit (10 minutes). For the sequential schedule, we tuned tile size and then flags on every kernel. For the joint strategy, the time limit per kernel is 20 minutes. Tuning tile size then flags offers 6.6% average speedup, while tuning them jointly offers only 1.9% average speedup. This is because while the individual tile size and flags search spaces are small, their joint search space is too large; as a result, traversing the search space in a random order fails to discover good candidates by the time limit. C. Search Strategies To show that XTAT-M allows various search strategies without changing the search formulation, we ran the search techniques from Section II-C (excluding exhaustive search) on fusion autotuning. This also evaluates the search strategies at finding good candidates in a large search space. We measured execution time on real hardware, using 1,000 or 10,000 candidate evaluations, depending on the benchmark’s time for one evaluation. We ran each search strategy on 10 replicas starting from the default configuration. We report speedup using randomly generated data and ignoring control flow. Figure 9 shows the average speedup over the default con- figuration. Fig. 10 in the Appendix shows the optimization trajectories for one example benchmark. We find rather simple evolution-based techniques (SA and EVO) reliably find better solutions than advanced model-based optimization techniques (MBO and RL). We hypothesize that the high-dimensional search spaces (2960 for AutoEncoder; up to 239568 for Efficient- Net) make it challenging to fit an accurate model without prior knowledge. Furthermore, the evolution-based techniques take less time to propose new candidates, reducing compute costs and overall tuning time. While SA and EVO are comparable for most benchmarks, SA is worse than EVO and RL on GraphNet models. With more samples, however, SA achieves Fig. 9: Fusion autotuning: average execution time speedup using different search strategies (starting from a default con- figuration) when allowing up to 1,000 or 10,000 samples (depending on benchmarks). Error bars show 95% confidence intervals over ten replicas. 11 the highest speedup. We conclude that when resources are limited (one or a few machines available for autotuning), EVO finds good configurations faster than other algorithms. V. RELA TEDWORK A. Autotuning in ML Compilers Autotuning has been effective at optimizing code in various domains [23]–[28]. We apply this technique to a multi-pass ML compiler. Recent search-based ML compilers [1]–[8] ap- ply autotuning at the kernel or subgraph level. Template-based approaches [1]–[7] are similar to XLA ’s lowering algorithm; based on a kernel’s subgraph, a loop structure template is used to generate code. Ansor [3] proposed a template-based approach that allows more flexible loop fusions compared to prior work. However, their tiling structure is still fixed, and their fusion capability is more limited than XLA ’s. Halide [5], [29]–[31] covers a larger space of possible loop implementa- tions compared to template-based approaches, but performed worse than FlexTensor [4] and Ansor [3]. Mind Mappings [32] and AKG [33] focus on operator-level optimizations and code generation for custom hardware accelerators. UnlikeXTAT, these prior works do not tune layout decisions. The value learning approach [9] first applied search to loop optimizations for an entire graph at once. However, its search must be applied in a single compilation stage, making it inapplicable to multi-pass production ML compilers, and it does not tune tensor layouts. This approach has been applied to inference graphs with up to 400 nodes, while our approach has been evaluated on both inference and training graphs with up to 500,000 nodes. DeepCuts [34] applies a greedy exploration guided by an analytical cost model to tune graph-level fusion decisions along with some GPU kernel parameters. However, its fusion capability is limited, and it is not obvious how to extend DeepCuts to support layout tuning at the graph level. Graph substitution approaches [10], [35] optimize entire tensor computation graphs, but work in a limited search space reachable via graph rewrites. Without exploding the number of rewrite rules, they cannot represent arbitrary fusions of tensor operations or change layouts of arbitrary tensors. GO [19] optimizes device placement, operator fusion, and operator scheduling decisions for an entire TensorFlow graph. However, it does not consider the effect of multiple compilation passes on the intermediate computation graph, so we cannot adopt their search formulation when dealing with a full compiler stack. Rammer [36] can jointly optimize inter- and intra- operator parallelism, but it does not address other kinds of optimizations, such as layout and fusion, addressed in this paper. Rammer’s approach is also inapplicable to TPUs, since TPUs do not support concurrent execution of multiple kernels. Many existing works use heuristics or analytical cost models to tackle a specific graph-level optimization, including operator fusion [21], [37], [38] and layout assignment [39]. B. Joint Autotuning Capability In a multi-pass compiler, changing a configuration for one optimization pass changes the search spaces for subsequent op- timizations, as explained in Section II-A. Generic autotuning frameworks, such as OpenTuner [28], require the entire search space to be specified upfront, thus disallowing search spaces that change dynamically. Our joint autotuning methodology is a generic method to formulate the interactions between multi- pass compiler optimizations. It is applicable to any multi- pass compiler and is not specific to the XLA compiler or XTAT. Therefore, it can be implemented in existing autotuning frameworks (if they can be extended to support dynamic search spaces), enabling them to perform joint optimizations. The approach used in most search-based ML compilers [1]– [9], inspired by Halide [29], supports joint optimizations by default. However, when a search space is large, it requires a cost model that can accurately evaluate a (partial) schedule or configuration, which is extremely challenging to create for an entire tensor graph. Therefore, most of these compilers optimize only one small subgraph at a time. While the value learning approach [9] can optimize an entire inference graph, it requires carefully-crafted feature engineering, which is not easily applied to new hardware. Furthermore, one cannot easily apply a Halide-like approach to multi-pass production compil- ers without completely reimplementing them. Our goal is to provide autotuning capability to such multi-pass compilers. C. Learned Cost Model Similar to prior works [2], [5], [7], [9], [22], [40]–[42], we use a learned cost model to accelerate autotuning. We additionally propose a pretraining-finetuning method to reduce training time while keeping the model up-to-date. VI. C ONCLUSION We proposed a search methodology that enables autotun- ing various graph-level and subgraph-level optimizations at different compilation stages for production ML compilers. Our search formulation allows solving optimization problems jointly or one-at-a-time, as well as using a spectrum of search strategies to solve them. Based on this, we developed an autotuner to tune the key optimization passes in the XLA TPU compiler. The execution time speedups on 150 ML models from Google’s workloads found by the autotuner averaged 5%, with many cases over 15%, and one improving by a factor of 2.4. We substantially reduced tuning time via a learned cost model. XTAT has been used in different ways to optimize produc- tion models. Compiler developers have usedXTAT to detect opportunities to improve the baseline heuristics multiple times. For instance, fusion autotuning led to a fix in the heuristics, yielding 18% latency reduction on a model served in produc- tion. Such improvements are invisible in our experiments as they have already been incorporated into the compiler. Besides being used by compiler developers,XTAT has been deployed to automatically tune tile sizes and flags for the most heavily- used production models in Google’s fleet everyday. ACKNOWLEDGMENT We thank Albert Cohen, Charith Mendis, Jacques Pienaar, Jason Ansel, and the reviewers for their insightful feedback. 12 REFERENCES [1] T. Chen, T. Moreau, Z. Jiang, L. Zheng, E. Y an, M. Cowan, H. Shen, L. Wang, Y . Hu, L. Ceze, C. Guestrin, and A. Krishnamurthy, “TVM: An Automated End-to-End Optimizing Compiler for Deep Learning,” in Proceedings of the 13th USENIX Conference on Operating Systems De- sign and Implementation, ser. OSDI ’18. USA: USENIX Association, 2018, p. 579–594. [2] T. Chen, L. Zheng, E. Y an, Z. Jiang, T. Moreau, L. Ceze, C. Guestrin, and A. Krishnamurthy, “Learning to Optimize Tensor Programs,” in Proceedings of the 32nd International Conference on Neural Information Processing Systems, ser. NeurIPS’18. Red Hook, NY , USA: Curran Associates Inc., 2018, p. 3393–3404. [3] L. Zheng, C. Jia, M. Sun, Z. Wu, C. H. Y u, A. Haj-Ali, Y . Wang, J. Y ang, D. Zhuo, K. Sen, J. E. Gonzalez, and I. Stoica, “Ansor: Generating High- Performance Tensor Programs for Deep Learning,” in14th USENIX Symposium on Operating Systems Design and Implementation , ser. OSDI ’20. USENIX Association, Nov. 2020, pp. 863–879. [4] S. Zheng, Y . Liang, S. Wang, R. Chen, and K. Sheng, “FlexTensor: An Automatic Schedule Exploration and Optimization Framework for Tensor Computation on Heterogeneous System,” in Proceedings of the Twenty-Fifth International Conference on Architectural Support for Programming Languages and Operating Systems, ser. ASPLOS ’20. New Y ork, NY , USA: Association for Computing Machinery, 2020, p. 859–873. [5] A. Adams, K. Ma, L. Anderson, R. Baghdadi, T.-M. Li, M. Gharbi, B. Steiner, S. Johnson, K. Fatahalian, F. Durand, and J. Ragan-Kelley, “Learning to Optimize Halide with Tree Search and Random Programs,” ACM Trans. Graph., vol. 38, no. 4, Jul. 2019. [6] B. H. Ahn, P . Pilligundla, A. Y azdanbakhsh, and H. Esmaeilzadeh, “Chameleon: Adaptive Code Optimization for Expedited Deep Neural Network Compilation,” inInternational Conference on Learning Repre- sentations, 2020. [7] M. Li, M. Zhang, C. Wang, and M. Li, “AdaTune: Adaptive Tensor Program Compilation Made Efficient,” in34th Conference on Neural Information Processing Systems, ser. NeurIPS’20, 2020. [8] N. V asilache, O. Zinenko, T. Theodoridis, P . Goyal, Z. DeVito, W . S. Moses, S. V erdoolaege, A. Adams, and A. Cohen, “Tensor Compre- hensions: Framework-Agnostic High-Performance Machine Learning Abstractions,”arXiv preprint arXiv:1802.04730, 2018. [9] B. Steiner, C. Cummins, H. He, and H. Leather, “V alue Learning for Throughput Optimization of Deep Learning Workloads,” inProceedings of MLSys Conference, 2021. [10] Z. Jia, O. Padon, J. Thomas, T. Warszawski, M. Zaharia, and A. Aiken, “T ASO: Optimizing Deep Learning Computation with Automatic Gen- eration of Graph Substitutions,” in Proceedings of the 27th ACM Symposium on Operating Systems Principles, ser. SOSP ’19. New Y ork, NY , USA: Association for Computing Machinery, 2019, p. 47–62. [11] TensorFlow, “XLA: Optimizing Compiler for TensorFlow,” https://www.tensorflow.org/xla, [Online; accessed 19-September-2019]. [12] N. Rotem, J. Fix, S. Abdulrasool, G. Catron, S. Deng, R. Dzhabarov, N. Gibson, J. Hegeman, M. Lele, R. Levenstein, J. Montgomery, B. Maher, S. Nadathur, J. Olesen, J. Park, A. Rakhov, M. Smelyanskiy, and M. Wang, “Glow: Graph Lowering Compiler Techniques for Neural Networks,”arXiv preprint arXiv:1805.00907, 2019. [13] Y . Xu, H. Lee, D. Chen, H. Choi, B. A. Hechtman, and S. Wang, “Automatic cross-replica sharding of weight update in data-parallel training,”CoRR, vol. abs/2004.13336, 2020. [14] N. P . Jouppi, C. Y oung, N. Patil, D. Patterson, G. Agrawal, R. Bajwa, S. Bates, S. Bhatia, N. Boden, A. Borchers, R. Boyle, P .-l. Cantin, C. Chao, C. Clark, J. Coriell, M. Daley, M. Dau, J. Dean, B. Gelb, T. V . Ghaemmaghami, R. Gottipati, W . Gulland, R. Hagmann, C. R. Ho, D. Hogberg, J. Hu, R. Hundt, D. Hurt, J. Ibarz, A. Jaffey, A. Jaworski, A. Kaplan, H. Khaitan, D. Killebrew, A. Koch, N. Kumar, S. Lacy, J. Laudon, J. Law, D. Le, C. Leary, Z. Liu, K. Lucke, A. Lundin, G. MacKean, A. Maggiore, M. Mahony, K. Miller, R. Na- garajan, R. Narayanaswami, R. Ni, K. Nix, T. Norrie, M. Omernick, N. Penukonda, A. Phelps, J. Ross, M. Ross, A. Salek, E. Samadiani, C. Severn, G. Sizikov, M. Snelham, J. Souter, D. Steinberg, A. Swing, M. Tan, G. Thorson, B. Tian, H. Toma, E. Tuttle, V . V asudevan, R. Walter, W . Wang, E. Wilcox, and D. H. Y oon, “In-Datacenter Performance Analysis of a Tensor Processing Unit,” inProceedings of the 44th Annual International Symposium on Computer Architecture, ser. ISCA ’17, 2017. [15] N. P . Jouppi, D. H. Y oon, G. Kurian, S. Li, N. Patil, J. Laudon, C. Y oung, and D. Patterson, “A Domain-Specific Supercomputer for Training Deep Neural Networks,”Commun. ACM, vol. 63, no. 7, p. 67–78, Jun. 2020. [16] E. Real, A. Aggarwal, Y . Huang, and Q. V . Le, “Regularized evolution for image classifier architecture search,” in Proceedings of the aaai conference on artificial intelligence, vol. 33, 2019, pp. 4780–4789. [17] C. Angermueller, D. Belanger, A. Gane, Z. Mariet, D. Dohan, K. Murphy, L. Colwell, and D. Sculley, “Population-Based Black- Box Optimization for Biological Sequence Design,” arXiv preprint arXiv:2006.03227, 2020. [18] C. Angermueller, D. Dohan, D. Belanger, R. Deshpande, K. Murphy, and L. Colwell, “Model-based reinforcement learning for biological sequence design,” inInternational Conference on Learning Represen- tations, 2019. [19] Y . Zhou, S. Roy, A. Abdolrashidi, D. Wong, P . Ma, Q. Xu, H. Liu, P . Phothilimtha, S. Wang, A. Goldie, A. Mirhoseini, and J. Laudon, “Transferable Graph Optimizers for ML Compilers,” inProceedings of International Conference on Neural Information Processing Systems, ser. NeurIPS’20, 2020. [20] J. Schulman, F. Wolski, P . Dhariwal, A. Radford, and O. Klimov, “Proxi- mal Policy Optimization Algorithms,”CoRR, vol. abs/1707.06347, 2017. [21] J. Roesch, S. Lyubomirsky, M. Kirisame, L. Weber, J. Pollock, L. V ega, Z. Jiang, T. Chen, T. Moreau, and Z. Tatlock, “Relay: A High-Level Compiler for Deep Learning,”arXiv preprint arXiv:1904.08368, 2019. [22] S. J. Kaufman, P . M. Phothilimthana, Y . Zhou, C. Mendis, S. Roy, A. Sabne, and M. Burrows, “A Learned Performance Model for Tensor Processing Units,” in Proceedings of Machine Learning for Systems, 2021. [23] R. C. Whaley and J. J. Dongarra, “Automatically Tuned Linear Alge- bra Software,” in Proceedings of the 1998 ACM/IEEE Conference on Supercomputing, ser. SC ’98, 1998. [24] M. Frigo and S. G. Johnson, “FFTW: an adaptive software architecture for the FFT,” in Proceedings of the 1998 IEEE International Confer- ence on Acoustics, Speech and Signal Processing, ICASSP ’98 (Cat. No.98CH36181), 1998. [25] G. Fursin, Y . Kashnikov, A. W . Memon, Z. Chamski, O. Temam, M. Namolaru, B. Mendelson, A. Zaks, E. Courtois, F. Bodin, P . Barnard, E. Ashton, E. Bonilla, J. Thomson, C. Williams, and M. O’Boyle, “Milepost GCC: Machine Learning Enabled Self-tuning Compiler,” International Journal of P arallel Programming, vol. 39, pp. 296–327, 2011. [26] J. Ansel, C. Chan, Y . L. Wong, M. Olszewski, Q. Zhao, A. Edelman, and S. Amarasinghe, “PetaBricks: A Language and Compiler for Algo- rithmic Choice,” inProceedings of the 30th ACM SIGPLAN Conference on Programming Language Design and Implementation, ser. PLDI ’09. Association for Computing Machinery, 2009. [27] P . M. Phothilimthana, J. Ansel, J. Ragan-Kelley, and S. Amarasinghe, “Portable Performance on Heterogeneous Architectures,” inProceedings of the Eighteenth International Conference on Architectural Support for Programming Languages and Operating Systems, ser. ASPLOS ’13. Association for Computing Machinery, 2013. [28] J. Ansel, S. Kamil, K. V eeramachaneni, J. Ragan-Kelley, J. Bosboom, U. O’Reilly, and S. Amarasinghe, “OpenTuner: An extensible frame- work for program autotuning,” in2014 23rd International Conference on P arallel Architecture and Compilation T echniques, ser. P ACT ’14, 2014, pp. 303–315. [29] J. Ragan-Kelley, C. Barnes, A. Adams, S. Paris, F. Durand, and S. Amarasinghe, “Halide: A language and compiler for optimizing parallelism, locality, and recomputation in image processing pipelines,” in Proceedings of the 34th ACM SIGPLAN Conference on Programming Language Design and Implementation, ser. PLDI ’13. Association for Computing Machinery, 2013. [30] T.-M. Li, M. Gharbi, A. Adams, F. Durand, and J. Ragan-Kelley, “Differentiable programming for image processing and deep learning in halide,”ACM Trans. Graph., vol. 37, no. 4, Jul. 2018. [31] R. T. Mullapudi, A. Adams, D. Sharlet, J. Ragan-Kelley, and K. Fata- halian, “Automatically Scheduling Halide Image Processing Pipelines,” ACM Trans. Graph., vol. 35, no. 4, Jul. 2016. [32] K. Hegde, P .-A. Tsai, S. Huang, V . Chandra, A. Parashar, and C. W . Fletcher, “Mind Mappings: Enabling Efficient Algorithm-Accelerator Mapping Space Search,” inProceedings of the 26th ACM International Conference on Architectural Support for Programming Languages and Operating Systems, ser. ASPLOS 2021. New Y ork, NY , USA: Asso- ciation for Computing Machinery, 2021, p. 943–958. 13 [33] J. Zhao, B. Li, W . Nie, Z. Geng, R. Zhang, X. Gao, B. Cheng, C. Wu, Y . Cheng, Z. Li, P . Di, K. Zhang, and X. Jin, “AKG: Automatic Kernel Generation for Neural Processing Units Using Polyhedral Trans- formations,” inProceedings of the 42nd ACM SIGPLAN International Conference on Programming Language Design and Implementation, ser. PLDI ’21. New Y ork, NY , USA: Association for Computing Machinery, 2021, p. 1233–1248. [34] W . Jung, T. T. Dao, and J. Lee, “DeepCuts: A Deep Learning Op- timization Framework for V ersatile GPU Workloads,” inProceedings of the 42nd ACM SIGPLAN International Conference on Programming Language Design and Implementation, ser. PLDI ’21. New Y ork, NY , USA: Association for Computing Machinery, 2021, p. 190–205. [35] Z. Jia, J. Thomas, T. Warszawski, M. Gao, M. Zaharia, and A. Aiken, “Optimizing DNN Computation with Relaxed Graph Substitutions,” in Proceedings of MLSys Conference, 2019. [36] L. Ma, Z. Xie, Z. Y ang, J. Xue, Y . Miao, W . Cui, W . Hu, F. Y ang, L. Zhang, and L. Zhou, “Rammer: Enabling Holistic Deep Learning Compiler Optimizations with rTasks,” in 14th USENIX Symposium on Operating Systems Design and Implementation , ser. OSDI ’20. USENIX Association, Nov. 2020, pp. 881–897. [37] Nvidia, “Nvidia TensorRT: Programmable Inference Accelerator,” 2017. [38] Z. Zheng, P . Zhao, G. Long, F. Zhu, K. Zhu, W . Zhao, L. Diao, J. Y ang, and W . Lin, “FusionStitching: Boosting Memory Intensive Computations for Deep Learning Workloads,”arXiv preprint arXiv:2009.10924, 2020. [39] Y . Liu, Y . Wang, R. Y u, M. Li, V . Sharma, and Y . Wang, “Optimizing CNN Model Inference on CPUs,” in2019 USENIX Annual T echnical Conference), ser. A TC ’19. Renton, W A: USENIX Association, Jul. 2019, pp. 1025–1040. [40] C. Dubach, J. Cavazos, B. Franke, G. Fursin, M. F. O’Boyle, and O. Temam, “Fast Compiler Optimisation Evaluation Using Code-feature Based Performance Prediction,” inProceedings of the 4th International Conference on Computing Frontiers, ser. CF ’07, 2007. [41] Z. Jia, S. Lin, M. Gao, M. Zaharia, and A. Aiken, “Improving the Accu- racy, Scalability, and Performance of Graph Neural Networks with Roc,” in Proceedings of MLSys Conference, I. Dhillon, D. Papailiopoulos, and V . Sze, Eds., vol. 2, 2020, pp. 187–198. [42] R. Baghdadi, M. Merouani, M.-H. Leghettas, K. Abdous, T. Arbaoui, K. Benatchba, and S. Amarasinghe, “A Deep Learning Based Cost Model for Automatic Code Optimization,” inProceedings of MLSys, 2021. 14 APPENDIX A. Additional Evaluation Results on Search Strategies Fig. 10: Fusion autotuning: optimization trajectories for one example benchmark. Shaded areas show 95% confidence in- tervals over ten replicas. In the experiment that compares different search strategies in Section IV -C, we collect the speedup trajectories of various search strategies over time on one example benchmark, shown in Fig. 10. We notice that RL has very high variance on most benchmarks compared to the rest, as also evidenced in Fig. 10. This means in the setting where we can run 10 search replicas in parallel and take the best, RL often achieves the most speedup compared to the others at the same number of samples, especially earlier in the search. Future work may consider incorporating prior knowledge, e.g. pretraining the models on a diverse set of graphs, to improve the performance and the consistency of model-based optimizations. B. Semantic Rules for XTAT-M In this section, we describe (a) the implementation of GenerateCandidatesfor simulated annealing, and (b) briefly present the semantics of operations in XTAT-M and derive two search steps in a joint layout-fusion tuning for the graph in Fig. 2. a) Implementation of GenerateCandidates for simulated annealing: As described in Section II-C, simulated anneal- ing uses a mutation operator, e.g., single-node, to mutate a given configuration and accept a new one based on an- nealing temperature. Fig. 11 presents an implementation of GenerateCandidatesfor simulated annealing. This implemen- tation utilizes a routine,Mu ta te, which implements the muta- tion operator, generating a new configuration from the current configuration. b) Semantics of operations inXTAT-M: Fig. 12 presents the semantics ofInferConfig, UpdateStore, Mutate (based on Fig. 11), and ApplyOpt. Specifically, to keep the discussion concise, we focus on a single-node mutation-based search strategy applied to tuning layout assignment and operator fusion optimizations. • InferConfig: This routine updates a configurationconfig for an optimizationop tid to be compatible with the graph 1: function GENERA TECANDIDA TES(op tid ,C) 2: c ←C[0] // C has one candidate. 3: c′←c // Init configs for all optimizations. 4: // Mutate only the config for optimizationop tid . 5: c′.configs[optid] ←Mutate(c.configs[optid]) 6: return {c′} 7: end function Fig. 11: Implementation ofGenerateCandidatesfor simulated annealing. g, an input to the optimization pass.InferConfigidentifies the nodes in g and config that have the same fingerprint fp(n) and carries forward the configurations inconfig for such nodes. For the other nodes in g, it pulls the best configurations found so far from the global ConfStore if present; otherwise, it generates optimization-specific defaults. • UpdateStore: When a search candidate configuration is evaluated and it performs superior to prior observed evaluations, then the candidate configuration is captured by updating the globalConfStore. • Mutate: Mu ta teconstructs a new configuration from the current configuration. We present a simplified rule for a single-node mutation, soMu ta tereturns a configuration change for a single node in the graph. • ApplyOpt: As described in Section II-B,ApplyOpt trans- forms an input graph by applying the optimization. A derivation of the joint layout-fusion tuning performed on the graph in Fig. 2 is presented in Fig. 13. For conciseness, we do not describe all the tensors involved in the graph. Specif- ically, we focus on the mutation of the layout configurations for tensors,t5 and t6, in the search step for layout, and focus on the add node in the search step for fusion. In each search step, the Mu ta teoperation for layout begins with the graph g, applies a layout mutation, and infers theconfig for fusion. Additionally, the first step performs theMu ta teoperation for fusion. Both steps apply the inferred fusion configuration and execute the output graph. Based on the evaluation, each search step updates the global store, i.e.,ConfStore. In the derivation, we note that applying a search candidate for layout in step 1 results in the addition of a copy node, while no copy is introduced when a different search candidate for layout is explored in step 2. 15 Fig. 12: Semantics of functionsInferConfig, UpdateStore, Mutate (for a single node), andApplyOpt in XTAT-M. infer-config fr o m_con f ig:= {tuple (fp (n),con f ig[ fp (n)])}, ∀(n).(n ∈g.Nodes ∧fp (n) ∈con f ig) fr o m_store := {tuple (fp (n),Con f Store[op tid ][fp (n)])}, ∀(n).(n ∈g.Nodes ∧fp (n) ̸∈con f ig∧fp (n) ∈Con f Store[op tid ]) fr o m_init := {tuple (fp (n),GetInitCon f ig(op tid ,g)[n])}, ∀(n).(n ∈g.Nodes ∧fp (n) ̸∈con f ig∧fp (n) ̸∈Con f Store[op tid ]) E ⊢ con f ig′:= In f erCon f ig(con f ig,g,Con f Store[op tid ]) ⇓E{con f ig′↦→{ fr o m_con f ig∪fr o m_store∪fr o m_init}} update-store new_con f ig:= {tuple (fp (n),con f igs[op tid ][fp (n)])}, ∀(n).(fp (n) ∈con f igs[op tid ]) old_con f ig:= {tuple (fp (n),Con f Store[op tid ][fp (n)])}, ∀(n).(fp (n) ̸∈con f igs[op tid ]∧fp (n) ∈Con f Store[op tid ]) E ⊢U pdateStore(Con f Store,con f igs) ⇓E{Con f Store[op tid ] ↦→{old_con f ig∪new_con f ig},∀(op tid ∈Con f Store)} Mutate layout {n1}∈ Nodes n 1 := {op,t1} op tid := layoutID con f ig[n1] := layoutt1 layout′t1 ∈rand(LayoutGen(t1)) ∧ (layoutt1 ̸= layout′t1 ) E ⊢ con f ig′:= Mu ta te(con f ig) ⇓E{con f ig′↦→{(n1,layout′t1 )}} apply-layout1 g; {n1,n2}∈ Nodes; {(n1,n2)}∈ Edg es∧(n2.tin == n1.tout) con f ig[n1] := l1 con f ig[n2] := l2 E ⊢ l1 == l2 ⇓FALSE E ⊢ g := ApplyOp t(layoutID,g,con f ig) ⇓E{g ↦→{g ∪{n1.con f ig.layouttout = l1,n2.con f ig.layouttin = l2}∪{Insert(copy,n1,n2)}} apply-layout2 g; {n1,n2}∈ Nodes; {(n1,n2)}∈ Edg es∧(n2.tin == n1.tout) con f ig[n1] := l1 con f ig[n2] := l2 E ⊢ l1 == l2 ⇓TR UE E ⊢ g := ApplyOp t(layoutID,g,con f ig) ⇓E{g ↦→{g ∪{n1.con f ig.layouttout = l1},n2.con f ig.layouttin = l2}}} Mutate fusion {n1}∈ Nodes n 1 := {op,t1} op tid := f usionID con f ig[n1] := 0 E ⊢ con f ig:= Mu ta te(con f ig) ⇓E{con f ig↦→{(n1,1)}} apply-fusion g; {n1,n2}∈ Nodes; {(n1,n2)}∈ Edges con f ig[n1] := 1 E ⊢ g := ApplyOp t(f usionID,g,con f ig)) ⇓E{g ↦→{g \{n1,n2}∪{n′ 2 := n1 ◦n2}} Fig. 13: Two search steps in a joint layout-fusion tuning for the graphs in Fig. 2: left for step 1 and right for step 2. The neighborhood size for the node’s fingerprint calculation used byConfStoreis set to 0 (ignoring neighborhood) in this example. {n1,n2,n3}∈ Nodes {(n1,n3),(n1,n4),(n2,n4)}∈ Edg es n 1 := {add,t1} n2 := {max,t2} n3 := {reshape,t3,t4} n4 := {conv,t5,t6,t7} g := c.graphs(layoutID) LayoutGen(t1) := LayoutGen(t3) := LayoutGen(t5) := {{0,2,1},{2,1,0},{1,0,2}} LayoutGen(t2) := LayoutGen(t6) := {{{0,2,1},{2,0,1}} Step 1: Tune layout & fusion E ⊢ con f ig:= Mu ta te(c.con f igs(layoutID)) ⇓E{con f ig↦→{(n4,layoutt5 ↦→{0,1,2}),(n4,layoutt6 ↦→{0,2,1})}} E ⊢ g′:= ApplyOp t(layoutID,g,con f ig) ⇓E{g′↦→{g ∪{n4.con f ig.layoutt5 = {0,1,2},n4.con f ig.layoutt6 = {0,2,1}}∪{Insert(copy,n1,n4)}} E ⊢ con f ig′:= In f erCon f ig(c.con f igs(f usionID),g′,Con f Store(f usionID)) ⇓E{con f ig′↦→{(n1,0),(n2,0),(n3,0),(n4,0),(copy,0)}} E ⊢ con f ig′:= Mu ta te(con f ig′) ⇓E{con f ig′↦→{(n1,1)} E ⊢ g′′:= ApplyOp t(f usionID,g′,con f ig′) ⇓E{g′′↦→{g′\{n1,n3,copy}∪{n1 ◦n3,n1 ◦copy}}} ExecuteGraph(g′′) E ⊢U pdateStore(Con f Store{layoutID : con f ig, f usionID: con f ig′})a ⇓E{Con f Store↦→{layoutID : {(n4,layoutt5 ↦→{0,1,2}),(n4,layoutt6 ↦→{0,2,1})}, f usionID: {(n1,1),(n2,0),(n3,0),(n4,0),(copy,0)}}} Step 2: Tune layout (fusion config is inferred) E ⊢ con f ig:= Mu ta te(c.con f igs(layoutID)) ⇓E{con f ig↦→{(n4,layoutt5 ↦→{1,0,2}),(n4,layoutt6 ↦→{0,2,1})}} E ⊢ g′:= ApplyOp t(layoutID,g,con f ig) ⇓E{g′↦→{g ∪{n4.con f ig.layoutt5 = {1,0,2},n4.con f ig.layoutt6 = {0,2,1}}} E ⊢ con f ig′:= In f erCon f ig(c.con f igs(f usionID),g′,Con f Store(f usionID)) ⇓E{c.con f igs(f usionID) ↦→{(n1,1),(n2,0),(n3,0),(n4,0)}} E ⊢ g′′′:= ApplyOp t(f usionID,g′,con f ig′) ⇓E{g′′′↦→{g′\{n1,n3,n4}∪{n1 ◦n3,n1 ◦n4}}} ExecuteGraph(g′′′) E ⊢U pdateStore(Con f Store,{layoutID : con f ig, f usionID: con f ig′})b ⇓E{Con f Store↦→{layoutID : {(n4,layoutt5 ↦→{1,0,2}),(n4,layoutt6 ↦→{0,2,1})}, f usionID: {(n1,1),(n2,0),(n3,0),(n4,0)}}} (g,2 steps f usion+layout tune) ⇝Optimal(g′′,g′′′) acontinues in the next line bcontinues in the next line 16 BenchPress: A Deep Active Benchmark Generator Foivos Tsimpourlas Meta AI Research University of Edinburgh F.Tsimpourlas@sms.ed.ac.uk Pavlos Petoumenos University of Manchester pavlos.petoumenos@manchester.ac.uk Min Xu Meta AI Research m1n@fb.com Chris Cummins Meta AI Research cummins@fb.com Kim Hazelwood Meta AI Research kimhazelwood@fb.com Ajitha Rajan University of Edinburgh arajan@inf.ed.ac.uk Hugh Leather Meta AI Research hleather@fb.com ABSTRACT Finding the right heuristics to optimize code has always been a difficult and mostly manual task for compiler engineers. Today this task is near-impossible as hardware-software complexity has scaled up exponentially. Predictive models for compilers have recently emerged which require little human effort but are far better than humans in finding near optimal heuristics. As any machine learning technique, they are only as good as the data they are trained on but there is a severe shortage of code for training compilers. Researchers have tried to remedy this with code generation but their synthetic benchmarks, although thousands, are small, repetitive and poor in features, therefore ineffective. This indicates the shortage is of feature quality more than corpus size. It is more important than ever to develop a directed program generation approach that will produce benchmarks with valuable features for training compiler heuristics. We develop BenchPress, the first ML benchmark generator for compilers that is steerable within feature space representations of source code. BenchPress synthesizes compiling functions by adding new code in any part of an empty or existing sequence by jointly observing its left and right context, achieving excel- lent compilation rate. BenchPress steers benchmark generation towards desired target features that has been impossible for state of the art synthesizers (or indeed humans) to reach. It performs better in targeting the features of Rodinia benchmarks in 3 differ- ent feature spaces compared with (a) CLgen - a state of the art ML synthesizer, (b) CLSmith fuzzer, (c) SRCIROR mutator or even (d) human-written code from GitHub. BenchPress is the first gener- ator to search the feature space with active learning in order to generate benchmarks that will improve a downstream task. We show how using BenchPress, Grewe’s et al. CPU vs GPU heuristic model can obtain a higher speedup when trained on BenchPress’s We release BenchPress’s source code on a publicly available repository at https://github.com/fivosts/BenchPress. This work was supported by the Engineering and Physical Sciences Research Council (grant EP/L01503X/1), EPSRC Centre for Doctoral Training in Pervasive Parallelism at the University of Edinburgh, School of Informatics. PACT ’22, October 10–12, 2012, Chicago,IL 2018. ACM ISBN 978-1-4503-XXXX-X/18/06. . . $15.00 benchmarks compared to other techniques. BenchPress is a pow- erful code generator: Its generated samples compile at a rate of 86%, compared to CLgen’s 2.33%. Starting from an empty fixed input, BenchPress produces 10×more unique, compiling OpenCL bench- marks than CLgen, which are significantly larger and more feature diverse. ACM Reference Format: Foivos Tsimpourlas, Pavlos Petoumenos, Min Xu, Chris Cummins, Kim Hazelwood, Ajitha Rajan, and Hugh Leather. 2018. BenchPress: A Deep Active Benchmark Generator. In PACT ’22: International Conference on Par- allel Architectures and Compilation Techniques (PACT), October 10–12, 2018, Chicago, IL. ACM, New York, NY, USA, 12 pages. 1 INTRODUCTION Estimating compiler optimization heuristics through predictive modeling has been shown to outperform human experts and reduce development time in previous studies [6, 8]. However, designing effective predictive models requires exten- sive and diverse training data to help learn accurate compiler opti- mization heuristics. Training data typically take the form of static code features in benchmarks and their label for optimization heuris- tics [18]. Static code features are used to characterize the behaviour of programs and they are typically derived at the (1) Syntax level - by traversing the Abstract Syntax Tree (AST) (e.g. count number of operations in a function) or the (2) Intermediate Representation (IR) of a program - with the help of compiler passes (e.g. count of each LLVM-IR [25] instruction type). As shown in Figure 1, predictive models learn to infer optimal heuristics for a program based on program features and inputs. Predictive models would be an elegant solution for generat- ing compiler heuristics, if only we did not face an acute shortage of benchmarks, both in quantity and diversity [ 8, 36]. The aver- age number of benchmarks used in performance tuning papers is 17 [2, 5, 6, 14, 22, 36]. Well established areas of machine learning meanwhile rely on orders of magnitude more data. ImageNet [10], for example, holds 1.3M images for training and 50k for valida- tion. A shortage of benchmarks in training leads to poor feature space coverage that degrades the performance of predictive mod- els [8, 16]. Cummins et al. [6] show that enhancing datasets with synthetic benchmarks, using their tool CLgen, can improve the arXiv:2208.06555v2 [cs.AI] 16 Aug 2022 PACT ’22, October 10–12, 2012, Chicago,IL Foivos Tsimpourlas, Pavlos Petoumenos, Min Xu, Chris Cummins, Kim Hazelwood, Ajitha Rajan, and Hugh Leather Figure 1: Training pipeline of a predictive model. performance of the Grewe et al. [ 18] partitioning task by 1.27x. However, a case study by Goens et al. [ 16] shows that CLgen’s synthetic benchmarks lack feature diversity with most generated benchmarks being small, repetitive and with little new features compared to existing benchmarks. We aim to address this with BenchPress, a targeted benchmark generator, that can generate compiler benchmarks with a desired set of features. In this work, we focus on generating OpenCL benchmarks, as predictive models for heterogeneous systems is a rapidly advancing field and training examples for them are very sparse. We developBenchPress, a BERT-based OpenCL benchmark gen- erator [11, 34] that targets and synthesizes benchmarks in desired parts of the feature space. We use active learning to choose parts of the feature space and beam search to steerBenchPress’s generated samples towards the requested features. We trainBenchPress with OpenCL code samples that we collect by mining BigQuery [17] and GitHub directly using its API [15]. We support composite data types and calls to user-defined functions in our dataset and benchmark generation. BenchPress is a bidirectional generative model and learns to generate code in any part of a sequence by jointly con- sidering left and right context. We achieve this with a new learnt token, the [HOLE], which hides a sequence from the input, whose length is unknown to BenchPress during training. BenchPress learns to fill [HOLE] by iteratively predicting an arbitrary number tokens that are likely to lead to a compiling function. BenchPress outperforms CLgen in the task of undirected pro- gram generation from a fixed input feed, generating 10×more unique OpenCL kernels that are 7.5×longer on average, with a compilation rate of 86% compared to CLgen’s 2.33%. BenchPress strongly outperforms benchmark synthesizers CLgen, CLSmith [1, 37], and human written code from GitHub in reaching close to the features of Rodinia benchmarks, developed by compiler experts. Finally, BenchPress uses active learning, specifically query by com- mittee [32], to search the feature space and find missing features to improve Grewe’s et al. [18] CPU vs GPU heuristic. Enhancing the heuristic’s dataset with BenchPress’s benchmarks improves the heuristic’s speedup relative to the optimal static decision by 50%, increasing it from 4% to 6%, when the maximum possible speedup for this task is 12%. In this paper, we present the following contributions: (1) We are the first to develop a feature-space agnostic, steerable code generator towards desired program features. (2) We develop an automated approach to rank the feature space of downstream tasks with active learning. (3) We enable bidirectional source code generation by inserting [HOLE] tokens in any part of a sequence. 2 MOTIVATION Figure 2 shows a two-dimensional slice of the Grewe’s et al. [18] feature space: number of computational instructions vs number of memory instructions. Figure 2 also shows how the OpenCL bench- marks found in the Rodinia suite map into this plane, represented as purple diamonds. We find much of this two dimensional space is uncovered. 54 of the 58 Rodinia examples cluster in the lower left corner, the rest of the space having only four examples. Any optimization decision for programs in this area of the space would not be accurate due to lack of representative examples. Figure 2: # Memory operations and # computational instruc- tions for (a) Rodinia benchmarks in purple diamonds and (b) CLgen’s samples in red dots. Generating samples with miss- ing features is vital for predictive modeling’s performance. CLgen attempted to address this problem by automatically gen- erating more training examples. However, the generated kernels lacked feature diversity and provided even poorer coverage of the feature space. Figure 2 represents their position in the 2D space as red dots. Almost all of them are concentrated in a corner covering a small percentage of the feature space. While CLgen can generate hundreds of millions of unique kernels, almost all of them will fail to compile. As the probability of having at least one illegal token in the kernel body increases with the number of tokens, only tiny kernels are valid. In our experiments in Section 5, the longest compiling CLgen kernel had 8 lines and 102 tokens. Given the small number of tokens in valid kernels, there is a high degree of repetitiveness in the generated corpus, not only in terms of features but also in terms of structure and functionality. As a result, this approach is not well suited to augmenting the training set with diverse feature bench- marks. There is a compelling need to generate training points for uncovered regions of the feature space and we attempt to address this need with BenchPress. In the following Sections, we discuss our approach and evaluation of BenchPress, comparing it to the existing state-of-the art for feature space coverage. 3 APPROACH We present BenchPress, a deep learning model for directed com- piler benchmark generation. BenchPress is the first steerable Short Title PACT ’22, October 10–12, 2012, Chicago,IL synthesizer that can synthesize compiling functions with target features. BenchPress steers its generation with a feature space- agnostic beam search algorithm to search the space and steer BenchPress’s generation towards the target features. Given a down- stream task, BenchPress learns what features to target in order to improve its performance by searching the space with active learn- ing. BenchPress’s language model is based on BERT [11], which we transform into a generative model. The key feature in BenchPress that enables bidirectional code generation is a new token, namely, the [HOLE] token. We train BenchPress to learn and understand how to iteratively fill holes of unknown length that can be found in any part of an input sequence by conditioning it on the left and right context of the[HOLE]. Later, this approach enables us to use beam search and steer benchmark generation into the feature space iteratively as it can regress to previously generated benchmarks with new holes and produce newer samples with better features. Figure 3 illustrates an overview of our approach. BenchPress consists of three main components: (1) Learning corpus collection and processing. (2) Source code language modeling. (3) Feature space search and benchmark generation. We discuss each step in the following subsections. Figure 3: BenchPress’s high-level approach. 3.1 Learning Corpus Modeling source code accurately requires large amounts of data [26] similarly to other deep learning tasks. We develop a tool to collect data from BigQuery’s GitHub dataset [17]. We also use GitHub’s API [15] and mine directly extra repositories that are not included in BigQuery. There are a few innovations in how we pre-process the code compared to previous works. First, we inline included header files recursively into source files to resolve type dependencies. Addi- tionally, we automatically extract custom data types (e.g. struct, typedef) and utility functions found in the unprocessed corpus and place them into header files that are accessible throughout BenchPress’s pipeline. This way, we resolve most type dependen- cies by retaining the functionality and semantics of the original, human-written programs. These two steps enable us to increase significantly the amount of compiling kernels we end up with in our training dataset. Second, we isolate kernels into single instances because BenchPress is trained on complete functions. From the previous steps, the type dependencies of each kernel are known and we automatically provide them to the compiler, retaining their compilability. Finally, we compile all kernels with Clang and reject those that do not compile. Next, we re-write identifiers by randomly sampling the alphabet, eliminating spurious naming patterns in the corpus. All kernels are padded to BenchPress’s sequence length and kernels that are longer than this are truncated to fit. This helpsBenchPress train its later indices’ positional embeddings more effectively, for which we have less training information compared to earlier indices. Finally, we derive a tokenizer by parsing the AST of all source code. We reserve tokens for all OpenCL keywords and all intrinsic OpenCL function name identifiers found in the official OpenCL specifica- tions [33]. We analyze the dataset and tokenize by word the most common function names and custom data type identifiers that we have collected. We encode all literals and infrequently used custom types and functions character by character to avoid exploding the size of the vocabulary. We define 5 meta tokens:[START], [END], [PAD], [HOLE], [ENDHOLE]. The derived tokenizer holds in total 2,201 unique tokens. 3.2 Language Modeling BenchPress is based on BERT [ 11], a Transformer-based model originally designed for natural language modeling. BERT is trained to predict words that have been randomly hidden by[MASK] tokens. This way BERT learns fitting words with respect to their position in a sequence and also the left and right context, i.e., the text sequence before and after the masked token to be predicted. This type of training helps BERT learn what words mean within a given context, improving downstream tasks that rely on that knowledge. While this is a useful property, it is not enough to turn BERT into a generative model. We also want to be able to extend a kernel by inserting an arbitrary number of tokens in arbitrary positions. We could iteratively add a [MASK] token to get one extra token at a time, until we have a full statement. This would be limiting. Each time the new token would be selected based on its probability of completing forming a plausible kernel. Every intermediate kernel in the iterative process would have to be plausible or almost plausible, which is not a general way for augmenting kernels. Clusters of [MASK] tokens could allow us to insert multiple to- kens in each iteration. This is still unsatisfactory. The number of [MASK] tokens in the cluster biases the kind of code that will be generated: if we ask such a generator to produce five tokens, it will give us a five token statement that could be expected to close this gap, not a five token sequence that could be the start of a much longer statement. We could place the left and right context to the edges of a sequence and fill intermediate positions with [MASK] tokens. BenchPress could predict a vocabulary or a stop token for a [MASK], allowing for arbitrary sequences. We test this configuration and sample a trained model with a fixed input feed. BenchPress is unable to learn the [MASK]s’ left and right context conditionally, when many [MASK]s are in a sequence, which leads to zero samples to compile or even resemble reasonable code. PACT ’22, October 10–12, 2012, Chicago,IL Foivos Tsimpourlas, Pavlos Petoumenos, Min Xu, Chris Cummins, Kim Hazelwood, Ajitha Rajan, and Hugh Leather What we do instead is to extend BERT’s functionality with a new pair of learnt tokens, the [HOLE] and the [ENDHOLE]. [HOLE] follows the same logic with [MASK], however the number of tokens that have been hidden behind it is unknown to the model during training. The model only learns to predict the first token of an arbitrarily long missing sequence. At inference-time, we iteratively predict the first token of the remaining sequence and re-insert it just before the [HOLE]. This way BenchPress learns to generate arbitrarily large code sequences within any part of a sequence. Figure 4: When a [HOLE] is inserted to a kernel at a random index, it hides a random number of tokens, unknown to BenchPress. On this example, BenchPress learns to predict the first hidden token, p. Figure 4 shows how a[HOLE] is inserted into a function to create a datapoint. A random starting index and a random length are selected. The choice of index and length are only restricted by a potential overlap of the prospective hidden sequence with any of the other meta token or the maximum hole length that is defined as a training parameter for the architecture as a percentage of each function’s length. When the specifications of a hole have been settled, the hidden sequence is discarded. Only the first token of it is kept as the target prediction for that hole. A hole can also represent an empty sequence, i.e. hiding 0 tokens. In this case, the target prediction during training is [ENDHOLE]. The training instances are randomly generated on demand, the entire space of possible instances is too large to be pre-generated. In this paper, we only insert 1 hole per training instance forBenchPress to learn. Multiple holes could be used during training, but this is not needed during BenchPress’s current benchmark generation task. 3.3 Benchmark Generation BenchPress’s synthesizer operates as a generative model with the help of [HOLE] / [ENDHOLE] tokens. It receives an input with 1 or more [HOLE] tokens and returns a completed benchmark. For each [HOLE], BenchPress predicts one token that fits in the sequence at the [HOLE]’s index, with respect to its left and right context. If the predicted token is not [ENDHOLE], it moves the [HOLE] and all subsequent tokens one position to the right and inserts the predicted token to the initial target index. This intermediate kernel is iteratively provided as an input for the next token prediction and the process is repeated until BenchPress predicts [ENDHOLE]. This marks a [HOLE] is complete and the final sample is returned, as shown in Figure 5. On its own, this process only augments kernels. We also make it the first to target desired parts of a feature space by repeatedly Figure 5: During sampling, BenchPress receives an input and predicts iteratively the fitting tokens. BenchPress predicts [ENDHOLE] to indicate a [HOLE] is complete. generating kernels, selecting the ones closer to the target features, inserting new holes, and generating new augmented kernels. We use beam search to steer generation. Given a target feature vector, BenchPress samples a starting, fixed input feed ‘kernel void [HOLE]’ and yields a collection of starting benchmarks. We reject benchmarks that do not compile and for the remaining we measure the Euclidean distance between their feature vectors and the target features. We select thetop-K can- didates that have the shortest distance from the target and we use them as inputs for the next generation. To improve diversity among promoted benchmarks we introduce randomness in the selection of top-K candidates: Each top-K sample, has a fixed probability 𝑝 = 0.15 to be replaced by another random candidate of its genera- tion. BenchPress lazily creates multiple different input instances for each selected candidate by placing a random [HOLE] of random length in order to synthesize a new sample. BenchPress generates a successive collection of benchmarks, of which K compiling ones with the shortest distance from the target again are selected with p-randomness and used as inputs. This search continues until a sample achieves a distance of 0 from the target, or until a threshold of generations (i.e. beam search depth) is exhausted. BenchPress returns the closest benchmark to the target’s features along with all beam search’s intermediate benchmarks that cover the model’s traversal of the feature space starting from the origin and ending near the target features. For the benchmark synthesis process, we use categorical sampling with temperature to sampleBenchPress’s probabilities. The sampling temperature, beam search’s width K and depth are defined as sampling parameters. In the worst case, BenchPress’s directed program generation is slow, ranging from a few seconds to one hour, as it typically requires thousands of language model inferences. However, BenchPressis the first program synthesizer that can target a set of desired program features. 3.4 Feature Space Search A steerable synthesizer allows the generation of benchmarks with desired features. However, the automatic selection of those parts of the feature space that are worth targeting is challenging and depends on the downstream task. Short Title PACT ’22, October 10–12, 2012, Chicago,IL BenchPress attempts to solve this by searching the feature space with query by committee [32], a well-known active learning tech- nique. We implement a committee of (a) 7 NN, (b) 7 k-NN and (c) 7 K-means models. We set their initial state by passively training on a small portion of the downstream task’s data. We sample the committee with thousands of random points in the space, we collect the predicted labels and measure the entropy for each sample. The entropy shows the level of uncertainty among the committee about the predicted label of a given point and is defined as: 𝐻 = − 𝑙𝜖𝐿∑︁ (𝑝(𝑙)∗log(𝑝(𝑙))) (1) where 𝐿is the set of all predicted labels and 𝑝(𝑙)the probabil- ity of label 𝑙 in the committee’s prediction set for a given input. The highest entropy point is an important feature vector to target and BenchPress steers benchmark generation towards it with the approach explained in 3.3. We collect the labels of generated bench- marks and we train incrementally the committee with them. Then, we sample it to find the next highest entropy point. We continue this process until we saturate the feature space.BenchPress’s com- mittee is agnostic to the downstream task or the feature space and its I/O dimensions are hyper-parameters selected with respect to the task’s feature and prediction dimensions. 4 EXPERIMENTAL SETUP We describe the configurations used in training BenchPress, and the parameters used in evaluation, namely (1) Feature Spaces - we use three different representations of program features, (2) Target Benchmarks - We use Rodinia benchmarks [5] and their features as the target for synthesis by BenchPress, (3) Comparison to SOTA - we compareBenchPress with code synthesizers and human written code in improving Grewe’s et al. heuristic model. 4.1 Platforms We trainBenchPress and conduct all our experiments on two 64-bit systems each having one Intel Xeon E5-2620 16-core CPU, 2x Nvidia GeForce GTX 1080 GPU and 32 Gigabytes of RAM. We use Ubuntu 18.04, PyTorch 1.9.1 [ 29], CUDA version 11.4 and Nvidia driver version 510.47.03. We use Clang-10 as BenchPress’s compiler and LLVM-10 to compile and execute InstCount and Autophase [ 20] extracting tools. For compatibility reasons, we are required to use Clang LibTooling from LLVM-6 to execute Grewe’s et al. [18] feature extractor. 4.2 Language Modeling for source code We collect OpenCL code from GitHub and split it into single func- tion instances. We ensure no kernels that come from benchmarks suites used in the evaluation are included in our corpus. We pre- process text, re-write variables and reject OpenCL kernels that do not compile. In total we mine 63,918 OpenCL kernels across 12,860 GitHub repositories and we successfully compile 19,637 of them (31% compilation rate). We train BenchPress on our OpenCL Corpus for 10M steps with a batch size of 32. For BenchPress’s BERT model parameters, we select 2 hidden layers, 12 attention heads. We set intermediate size, hidden size and max position embeddings to 768. We set the maximum length of holes to be 90% of a kernel’s token length, i.e. a hole can hide almost all tokens of a training instance. We optimize the model using Adam optimizer with a learning rate that reaches a maximum of 45𝑥10−6 after 20,000 warmup steps and decays linearly over the remaining training steps. We trainBenchPress’s language model to a final loss value of 0.28. 4.3 Feature Spaces Compiler predictive models use static code features to represent programs and learn optimisation heuristics. A vector of indepen- dent characteristics represent a single program. Each of them are typically an integer or float value. Features are extracted at the Syntax level by traversing the AST or at the IR level using the com- piler’s middle end (e.g. LLVM-IR). A feature space is the collection of all possible program feature vectors. BenchPress is a generative model that can be steered to gen- erate samples for a desired part of the feature space. We evaluate BenchPress on three source feature representations we find across the literature, (a) Syntax-level Grewe’s et al. features [18], (b) IR- level LLVM-InstCount [25] and (c) IR-level Autophase [20]. Grewe’s et al. features are extracted with Clang’s LibTooling and used to train their predictive model on the CPU vs GPU task for OpenCL kernels. This feature space holds 8 dimensions. 4 di- mensions describe the number of 1) computational, 2) relational, 3) atomic and 4) memory access instructions. The feature space also counts the different type of memory instructions, local memory or coalesced. Finally, the computational to memory and coalesced to memory ratios are defined. InstCount is a standard pass provided by LLVM-IR framework and used in Compiler Gym by Cummins et al. [7]. InstCount holds 70 dimensions: 67 dimensions each counting all 67 LLVM-IR in- struction types and total number of 1) instructions, 2) basic blocks and 3) functions. Autophase by Huang et al. [20] holds 56 dimen- sions. While many of the features used in Autophase are shared with InstCount, they introduce new ones such as number of input arguments to PHI Nodes or total number of memory instructions. On the other hand, they do not include the count of some LLVM instructions that are not considered to contribute to a program’s representation, e.g. CatchPad instruction. 4.4 Analysis of BenchPress and CLgen language models CLgen [6] is the current state of the art in OpenCL benchmark gen- eration. Its synthetic benchmarks improve the accuracy of Grewe’s et al. predictive model [18] by 1.27×. However, Goens et al. [16] perform a case study and show evidence that CLgen’s synthetic benchmarks do not improve the quality of training data and, con- sequently, performance of predictive models. They show that a predictive model in fact performs worse with synthetic benchmarks as opposed to human written benchmarks or code from GitHub. This study motivates us to perform an analysis of BenchPress’s language model, BERT, with CLgen in the task of undirected pro- gram generation. In this first experiment, we reproduce CLgen using the authors’ artifacts and we sample it with a fixed input ‘kernel void’ to collect a dataset of unique OpenCL kernels. We use BenchPress on the same generative task and sample the model PACT ’22, October 10–12, 2012, Chicago,IL Foivos Tsimpourlas, Pavlos Petoumenos, Min Xu, Chris Cummins, Kim Hazelwood, Ajitha Rajan, and Hugh Leather with the same fixed input‘kernel void [HOLE]’to obtain another dataset of unique benchmarks. In this experiment we focus on the language model’s inference performance. We compare both gener- ative models on their throughput, their ability to create compiling code, feature distribution and code size. In this experiment, we do not direct program generation. BenchPress generates compiling kernels in a single inference step. 4.5 Targeted Benchmark Generation Next, we evaluate BenchPress’s ability to steer towards desired program features. We use well-established compiler benchmarks as our reference and target their features within this space. These benchmarks usually perform intensive operations, such as matrix multiplications or FFT analysis, they contain hundreds of computa- tional and memory instructions and are specifically fine-tuned by experts to exercise compilers from different angles. As a result, we believe features in these benchmarks provide a good target to assess performance of BenchPress’s ability to target complex features. We choose target benchmarks within the Rodinia suite [ 4, 5] as it is widely used in the literature [ 6, 8]. Similar to the train- ing corpus, we collect the suite’s source files, we inline header files and dependent OpenCL libraries into them, we split kernels into single source files and reject those that do not compile. In total, we collect 61 target Rodinia benchmarks out of which 58 compile. For the remaining benchmarks, we collect their features using the feature extractors for Grewe’s et al., InstCount and Au- tophase feature spaces [18, 20, 25]. We target the feature vectors of these benchmarks and request BenchPress to generate at least one matching benchmark for each. We end up with three collective syn- thetic benchmark datasets, one for each feature space, that contain code with features matching Rodinia benchmarks. For each Ro- dinia benchmark’s target feature vector, we measure the minimum Euclidean distance to it achieved between BenchPress, code from GitHub, CLgen and CLSmith [1, 37]. For GitHub’s and CLSmith’s kernels, we use SRCIROR [21] to apply code mutations exhaustively with beam search. To make our experiment more intuitive we use two datasets for GitHub: a) GitHub consisting of all OpenCL kernels we collected and b) GitHub-768, a proper subset of GitHub which contains only the kernels that do not exceed BenchPress’s sequence length of 768 tokens. Since BenchPress benchmarks’ size are restricted to the architecture’s sequence length, we feel it is important to make this distinction in order to present a view of BenchPress’s actual performance on features that may be unreachable within the current sequence length. For example, it may be impossible to generate 2,000 computational instructions within 768 tokens. For such cases, we believe GitHub-768 with its equally restricted sequence length would allow for a fairer comparison. For all three feature spaces, we weed out the Rodinia benchmarks that have an exact matching sample (i.e. a Euclidean distance of 0) in GitHub-768. Since we already have matching samples for them, we do not need to target them withBenchPress or any other generative model. However, we do not skip benchmarks whose features exist only in GitHub’s full dataset as we wanted to explore the feasibility of using BenchPress to generate a sample with the same features but smaller sequence length. Applying this restriction we end up with 22 Rodinia benchmarks for Grewe’s et al., 52 for InstCount and 36 for Autophase feature spaces. 4.6 Active Learning for Feature Selection BenchPress’s steerable generation is vital for searching the feature space while also finding useful features to target with active learn- ing. In this experiment, we evaluateBenchPress in the downstream task of training the predictive model proposed by Grewe et al. [18], a well-tested problem used by many baseline models. Grewe et al. train a decision tree model to predict the optimal device to execute a benchmark, choosing between a CPU and a GPU. They measure their model’s performance as speedup achieved with using the predicted device for execution versus statically executing all benchmarks on the GPU. To train the predictive model, they use OpenCL benchmarks from 7 well-known benchmarks suites [6, 18]. In this experiment, we reproduce Grewe’s et al. heuristic using their artifact and we also retrain it with datasets enriched with executable benchmarks from BenchPress using active learning and passive learning (i.e. targeting random parts of the feature space instead of searching it), CLgen and GitHub. We measure the speedup over static mapping for each of them. To collect our evaluated datasets, we execute OpenCL bench- marks with CLDrive [6] by Cummins et al. CLDrive automatically generates inputs and drives kernels to the hardware. It measures the execution time per device across thousands of runs and it re- jects kernels that produce runtime errors, do not modify any of the inputs (no output) or modify them differently for each run (not deterministic). For (a) the 7 human-written benchmarks suites, (b) BenchPress, (c) CLgen and (d) GitHub, we execute their kernel on CLDrive using a range of different local and global size configura- tions. We label each instance with the fastest measured device (the CPU or the GPU), in the same way Cummins et al. [6] and Grewe et al. [18] performed their evaluation. 5 RESULTS AND ANALYSIS In this section, we show our experiments’ results and compare BenchPress with state of the art techniques in OpenCL benchmark synthesis. We present case studies of (a) BenchPress’s throughput as a generative model compared to CLgen, (b) its ability to steer benchmark generation towards desired features and (c) its perfor- mance in searching the feature space to enhance a downstream task’s performance. 5.1 Analysis of BenchPress and CLgen language models We perform an analysis ofBenchPress and CLgen as language mod- els and compare them in generating a collection of benchmarks from a fixed input feed, ‘kernel void [HOLE]’ and ‘kernel void’ respectively. We compare the two approaches measuring (a) the generative models’ throughput and (b) the quality of their generated benchmarks in terms of code size and features. In this experiment, we do not use any directed search or iterative ap- proach for BenchPress’s generation. We perform this evaluation to measure how BERT, BenchPress’s underlying language model, compares with CLgen as a generative model. Table 1 presents the Short Title PACT ’22, October 10–12, 2012, Chicago,IL # unique benchmarks # compiling benchmarks compilation rate max tokens max inst (LLVM-IR) time per sample (ms) BenchPress 190,460 142,607 86% 750 161 162 CLgen 1,564,011 13,035 2.33% 102 32 103 Table 1: Throughput comparison between BenchPress and CLgen on generated OpenCL benchmarks when BenchPress does not use feature-directed program generation. aggregate measurements for the generated benchmarks using both approaches. Figure 6: Probability distribution of (a) token length and (b) LLVM-IR Instruction count among BenchPress’s and CLgen’s generated benchmarks. BenchPress’s benchmarks presented here are generated at a single inference step without itera- tively directing program synthesis. Compilation rate and code quality. BenchPress generates over 10×more unique compiling benchmarks than CLgen. This result is observed despite BenchPress generating 8×fewer unique bench- marks than CLgen. The compilation rate with BenchPress is 86% while CLgen has an exceedingly small rate of 2.3%. BenchPress’s largest sample is 750 tokens compiling to 161 LLVM-IR instruc- tions. This is a 7.5×and 5×increase in number of tokens and number of LLVM-IR instructions compared to CLgen’s largest ker- nel. The only drawback of BenchPress compared to CLgen is that it is considerably slower in generating candidates. This is because the transformer-based architecture in BenchPress is significantly larger in number of parameters than CLgen’s LSTM. Additionally, BenchPress tends to generate longer kernels than CLgen, necessi- tating more inference steps and longer generation time. In Figures 6a and 6b, we show the frequency distribution of the number of tokens and number of LLVM-IR instructions for compiling kernels for both datasets. To visualize our results better, we focus on synthesized kernels with token lengths ≤100 and instructions lengths ≤25 where the vast majority of benchmarks are found. Most of BenchPress’s benchmarks are found to have 20 to 80 tokens and 3 to 16 LLVM-IR instructions. The majority of CLgen’s benchmarks are found to have 5 to 45 tokens and only up to 4 LLVM-IR instructions. 94% of CLgen’s generated benchmarks have only 1 instruction when compiled to LLVM-IR. We analyze the dataset to explain this phenomenon and find CLgen generates a lot of comments, repeated dead statements and awkward non- human-like code such as multiple semi-colons. These results agree with the case study by Goens et al. [16] that shows the AST depth distribution of CLgen’s code is significantly narrower compared to code from GitHub or standard benchmarks. Feature space coverage. To further enhance our comparison, we perform an analysis on the feature space coverage ofBenchPress’s and CLgen’s synthesized programs in all three feature spaces. Fea- ture coverage is the most critical metric when evaluating the effec- tiveness of a benchmark synthesizer for predictive modeling. We use Principal Component Analysis (PCA-2) to represent the feature spaces in an easy to visualize 2-dimensional space. In Figures 7a, 7b and 7c we show the extent of feature space covered by candidates in the two approaches. CLgen’s samples are clustered around the origin, while there is one outlier for Autophase and two for Grewe’s et al. and InstCount features. Candidates generated by BenchPress are more scattered achieving a much wider coverage of the feature space. 5.2 Targeted Benchmark Generation We use beam search to generate samples that target desired parts of the feature space. We compareBenchPress with human-written benchmarks from GitHub and synthetic benchmarks from CLgen and CLSmith in targeting the features of Rodinia benchmarks on three feature spaces. We use SRCIROR code mutator with beam search to collect GitHub and CLSmith benchmarks with closer fea- tures. For each target benchmark, we gather one OpenCL kernel per evaluated dataset whose features have the minimum available Euclidean distance from the target features. Figures 8a, 8b and 8c show the relative proximity of each benchmark to the target. This proximity is the complement of the relative distance of the two kernels, i.e, 1 minus the distance between the two kernels in the feature space relative to the distance of the Rodinia kernel from the axes origin. This allows us to express the quality of the match with an intuitive 0% to 100% scale: 100% means the two kernels have the same features, 0% means the best kernel is as close to the target as an empty kernel. We mark perfect matches with a white asterisk (*). Performance on syntactic features. On Grewe’s et al. feature space, BenchPress generates kernels that are the closest ones in features for all 22 Rodinia Benchmarks compared to CLgen and CLSmith, PACT ’22, October 10–12, 2012, Chicago,IL Foivos Tsimpourlas, Pavlos Petoumenos, Min Xu, Chris Cummins, Kim Hazelwood, Ajitha Rajan, and Hugh Leather Figure 7: PCA-2 representation of feature space coverage of BenchPress and CLgen for (a) Grewe’s et al., (b) InstCount and (c) Autophase feature spaces. In this experiment, BenchPress’s generation is undirected and no iterative space search is performed. and 20 out of 22 compared toGitHub and GitHub-768. BenchPress synthesizes an exact match (100% relative proximity) for 14 target benchmarks. We pick out and discuss a few examples from our results. The absolute distance achieved for ‘nw-1’ and ‘ellipse_opt’, is 1.0. For both targets, almost all features match except for one missing in- struction (coalesced mem access and atomic inst respectively). For ‘hotspot’ GitHub and BenchPress produce a candidate kernel with exact matching features. However, BenchPress generates the matching candidate kernel in 421 tokens, unlike GitHub’s closest benchmark that has 798 tokens. For the two target benchmarks that BenchPress’s candidates were not closest to, we found onlyGitHub contains better samples for ‘com_dwt-3’ and and ‘gpu-1’, while BenchPress does not. We find both benchmarks to be fairly large (901 and 5,200 tokens respectively) and BenchPress cannot reach these features within 768 tokens. For the same reason,GitHub-768, CLgen and CLSmith does worse than BenchPress on these targets. Performance on LLVM IR features. Autophase and InstCount features are extracted from the LLVM-IR of a program that has been compiled with -O1 flag to apply basic optimisations such as dead code elimination. BenchPress occasionally generates re- peating operations that a compiler will remove or numerical op- erations that may be reduced to simple assignments. Owing to these optimisations, we find targeting benchmarks on these two feature spaces is more challenging than Grewe’s et al. syntax-level features. With InstCount features, BenchPress generates candi- dates whose features completely match 2 out of the 52 Rodinia benchmarks. Among the remaining 50, BenchPress outperforms CLgen, CLSmith, GitHub and GitHub-768 for all target benchmarks, achieving higher proximity.SRCIROR significantly improvesGitHub leading to GitHub+SRCIROR to achieve better proximity for 18 out of 52 Rodinia benchmarks compared toBenchPress. On Autophase features, BenchPress generates candidates matching the same 2 tar- get benchmarks, while outperforming CLgen, CLSmith and GitHub on 30 out of 36 Rodinia benchmarks in total. GitHub+SRCIROR per- forms better than BenchPress for 8 out of 36 target benchmarks and produces an exact match for ‘hotspotKernel’. We previously explain the importance of having diverse features in compiler benchmarks and we show, in Figure 2, how sparse Ro- dinia benchmarks are on Grewe’s et al. reduced feature space and how CLgen fails to provide any additional features. Now we intro- duce into this 2-dimensional space allBenchPress’s kernels that are generated while performing directed space search to target Rodinia benchmarks and we present them in Figure 9. BenchPress densely populates the space around the target benchmarks that are clus- tered around the lower left corner. We findBenchPress’s samples progressively converge to the target benchmark features with suc- cessive generations. For example, BenchPress targets ‘com_dwt-3’ at 385 computational and 137 memory instructions, starting from the axes origin and attempting to reach its features from different directions. One of the directions prevail but does not manage to exactly reach the target. The same happens for the top right point, ‘gpu-1’. BenchPress’s samples get closer developing a straight line from the origin to 1,000 computational and 100 memory instruc- tions. At this point BenchPress is restricted by its sequence length and cannot augment further its samples. This is depicted by its attempt to reduce the distance by swapping the two instruction types within the same token length, forming a perpendicular line with a negative slope. We argue the area of Grewe’s et al. feature space that BenchPress can cover within 768 tokens to be the area of the triangle formed by the intersections of the axes with the extension of the negative slope line developed by BenchPress’s samples. Summary - BenchPress vs GitHub vs CLgen vs CLSmith. 6 of the targeted Rodinia benchmarks exceed BenchPress’s maximum se- quence length of 768 tokens. In LLVM-IR feature spaces, care must be taken to generate code that will not be removed by compiler optimisations. This is a difficult challenge for source code gener- ative models. However, our results demonstrate that BenchPress can generate OpenCL kernels that approach target human-written benchmarks compared to GitHub code and CLgen candidates. Our experiments also show BenchPress is dramatically better in all cases than CLgen, the current state of the art in OpenCL synthetic benchmark generation. We further elaborate on BenchPress’s per- formance in the next subsections. 5.3 Active Learning for Feature Selection We combineBenchPress’s ability to generate benchmarks targeting desired features with active learning in order to generate bench- marks that improve the training of the Grewe et al. heuristic. We evaluate this against passive training withCLgen, GitHub code, and Short Title PACT ’22, October 10–12, 2012, Chicago,IL Figure 8: Relative proximity to each Rodinia benchmark of the candidate kernel with the closest features. We report the best match for seven datasets ( BenchPress’s, CLgen’s, GitHub’s and GitHub-768’s datasets also combined with exhaustive mutations with SRCIROR) over three feature spaces ((a) Grewe’s et al., (b) InstCount and (c) Autophase). Relative proximity is 1 minus the distance of the two kernels in the feature space relative to the distance of the Rodinia benchmark from the axes origin. 100% means an exact match in features and is highlighted with a white asterisk (*). A score towards 0% indicates the closest match is closer to the axes origin than the benchmark, i.e., a very small or empty kernel. BenchPress with randomly selected target features. All approaches augment the same baseline training set that is taken from [6], con- taining 7 benchmark suites1. Table 2 shows the effect of each ap- proach on the predictive power of the heuristic. Training only on 1The benchmarks have been updated with a wider range of global and local sizes. PACT ’22, October 10–12, 2012, Chicago,IL Foivos Tsimpourlas, Pavlos Petoumenos, Min Xu, Chris Cummins, Kim Hazelwood, Ajitha Rajan, and Hugh Leather Figure 9: # Memory operations and # computational instruc- tions for (a) Rodinia benchmarks in purple diamonds, (b) CLgen’s samples in red dots and BenchPress’s benchmarks in green crosses after performing directed search for all Ro- dinia benchmarks. Speedup % Precision Recall Specificity Benchmarks +4% 0.81 0.86 0.61 BenchPress-AL +6% 0.84 0.86 0.64 BenchPress-P +1% 0.84 0.85 0.48 CLgen -1% 0.52 0.86 0.43 GitHub +1% 0.85 0.83 0.61 Table 2: Grewe et al. heuristic model’s performance, preci- sion, recall, and specificity when trained on each technique. Speedup is the geometrical mean of speedups over all bench- marks relative to the optimal static decision, i.e. running on the GPU. Precision, recall, and specificity treat GPU labels as positive and CPU labels as negative. human written benchmarks improves the heuristic’s performance by 4%, as shown in Table 2’s first row. To understand the maxi- mum achievable improvement in the heuristic, we compute the best speedup ( = 12%) that is achieved if the model chooses the optimal device as opposed to always picking the GPU. For 71% of the benchmarks, GPU is the optimal device, so no speedup improve- ment is possible. For the remaining 29% benchmarks, predicting the ‘CPU’ label correctly with Grewe et al. will result in a speedup improvement. BenchPress using active learning (BenchPress-AL) clearly out- performs all other approaches in terms of average speedup, improv- ing it by 6%. When trained on BenchPress with passive/random feature selection ( BenchPress-P), the speedup achieved is only 1%. To our surprise, the same speedup is achieved with GitHub, which is worse compared with training only on the original bench- mark suites. We further analyze the dataset collected from GitHub code and we find it to be imbalanced with 90% of its training in- stances are labelled as ‘GPU’. This leads the model having a higher precision of 0.85, i.e. predicting correctly that a kernel should ex- ecute on the GPU, but falling short when it comes to correctly Figure 10: BenchPress’s performance enhancement of Grewe et al. heuristic model when using active learning compared to passively targeting random parts of the feature space over the course of 10 sampling epochs. predicting the ‘CPU’ label. Training the heuristic with CLgen ac- tually leads to a slowdown: it is 1% slower to execute kernels on the predicted devices compared to statically executing everything on the GPU, the baseline device. We analyze CLgen’s dataset and observe the opposite pattern found in GitHub’s dataset. 63% of its training data execute faster on the CPU than on the GPU. This is a direct consequence of CLgen generating small benchmarks that are poor in features, as the CPU may be slower than the GPU but the large overhead of transferring data to the GPU makes the CPU a better choice for small workloads. CLgen containing too many CPU-labeled kernel explains the heuristic’s low precision and speci- ficity, as it becomes biased to select the CPU very often leading to a slowdown. Our main motivation behind using active learning is that it gives BenchPress the ability to target directly those parts of the feature space that will maximize a downstream task’s performance. To assess the active learner’s performance, we compare the Grewe et al. heuristic’s speedup when trained on BenchPress’s bench- marks that target areas of the feature space selected by the active learner versus benchmarks that target random features. In both cases, we execute BenchPress for the same amount of time, 10 sampling epochs (i.e., performing steered generation for 10 target feature vectors). In Figure 10, we show the speedup achieved by the heuristic when trained on the data collected at that step. Using active learning to target features, BenchPress’s dataset improves the heuristic’s speedup by 50% after 5 sampling steps, from 4% to 6%. Targeting random features never leads to a speedup higher than 1%. BenchPress can still develop the same speedup by targeting random features if infinite amount of time was available. Our ac- tive learner ensures that missing features are going to be quickly targeted, improving the state of the art within 5 sampling epochs. 6 CONCLUSION Predictive models for compilers have been shown to outperform compiler experts but they are restricted by the amount and quality of training data they are exposed to. What is needed is an approach that can synthesize benchmarks and enhance datasets with missing features. In this paper we propose BenchPress, a powerful code generator that uses active learning to search the feature space and Short Title PACT ’22, October 10–12, 2012, Chicago,IL steers generation towards desired features. BenchPress generates 10×more and 7.5×larger undirected benchmarks with 37×greater compilation rate than CLgen - a state of the art compiler bench- mark generator - from a fixed input feed. BenchPress outperforms CLgen, CLSmith, code from GitHub and applied mutations with SRCIROR in generating OpenCL kernels that target the features of Rodinia benchmarks developed by human experts. BenchPress applies active learning to enhance Grewe’s et al. dataset with bench- marks with missing features and leads to improving the heuristic’s speedup by 50%. We hope this work to demonstrate a sustainable method to direct feature space search of program generation and that BenchPress’s release to researchers will enable research in related domains. 7 RELATED WORK BenchPress is inspired by BERT, a representation model by Devlin et al. [11]. Contrary to previous techniques [30, 31], BERT learns on unlabeled text data by jointly conditioning on both left and right context. BERT enables multiple applications of this architecture to a wide variety of difficult machine learning tasks, including programming languages. In CuBERT [24], Kanade et al. apply BERT over Python programs and evaluate it on finding typical mutation faults. In CodeBERT [13], Feng et al. fine-tune BERT to perform NL-PL and PL-NL transformations. In this work, we extend BERT to a bidirectional generative model, with the help of [HOLE] token. Cummins et al. [ 6] develop CLgen, a deep learning generator based on LSTM [ 23] for OpenCL programs. They try to tackle the compiler benchmark shortage by providing synthetic bench- marks as training data for compiler heuristics. The authors present the Grewe et al. [ 18] heuristic model improved its performance by 1.27×when trained on their synthetic benchmarks. However, Goens et al. [16] show that training with CLgen’s synthetic sam- ples lead to a slowdown compared to training on human-written benchmarks only. To explain this, they measure the AST depth of CLgen’s samples and show it is 3×smaller compared to human- written benchmarks and code from GitHub and poor in features, therefore unrealistic. This motivates us to develop BenchPress, which produces 10×more unique kernels that are 7.5×larger on average. In 2019, Nye et al. develop SketchAdapt [ 28], which uses a generator-synthesizer [3, 12] to generate program sketches given I/O specifications. The synthesizer samples sketches and the gener- ator fills tokens with statements. SketchAdapt performs better than other architectures [3, 12], however it samples only a pre-defined pool of operations, which restricts its diversity. Bruen et al. [9], propose a Tree2Tree approach for code generation using VAE. They encode AST nodes using Tree-LSTMs (Tai et al. [35]) and train their model on C++ functions. They test their approach against a VAE with an LSTM Seq2Seq model. They use their model as a synthesizer by sampling random AST representations which they extend to new programs. Their Seq2Seq model achieves a com- pilation rate of up to 67% with greedy search, however this happens because the model greedily selects the most probable labels, lead- ing to repetitive samples. When sampling with temperature, their Tree2Tree architecture is able to generate a wider variety of sam- ples, but only achieves a compilation rate of 22%, which translates to a few functions. Gupta et al. [19] develop SED, a two-stage generator. A synthe- sizer receives I/O specifications and generates programs likely to satisfy them and a neural debugger applies program repair to reform them into functions that match specifications. Gupta et al. evaluate three synthesizer architectures and measure (a) the correctness of generated programs across tests and (b) the accuracy of their debugger to repair code. While SED is an innovative work, Karel is a small-scale language and SED’s generative performance on a complex programming language is not evaluated. Faustino et al. develop Anghabench [8] to tackle the benchmark shortage [6, 36]. Anghabench is a collection of C programs mined from GitHub. In order to make it compilable, they use Psyche-C [ 27] type infer- ence engine to apply type reconstruction and resolve dependencies. Structs, unions and other composite data types are omitted or re- declared with primitive types. Their benchmarks are compiling, but cannot be executed. Compared to AnghaBench, BenchPress resolves type dependencies of composite types and user-defined functions without changing the functionality or semantics of pro- grams. PACT ’22, October 10–12, 2012, Chicago,IL Foivos Tsimpourlas, Pavlos Petoumenos, Min Xu, Chris Cummins, Kim Hazelwood, Ajitha Rajan, and Hugh Leather REFERENCES [1] [n.d.]. https://github.com/ChrisLidbury/CLSmith. [Online; accessed 25-Apr- 2022]. [2] R. Bagrodia, R. Meyer, M. Takai, Yu-An Chen, Xiang Zeng, J. Martin, and Ha Yoon Song. 1998. Parsec: a parallel simulation environment for complex systems. Computer 31, 10 (1998), 77–85. https://doi.org/10.1109/2.722293 [3] Matej Balog, Alexander Gaunt, Marc Brockschmidt, Sebastian Nowozin, and Daniel Tarlow. 2016. DeepCoder: Learning to Write Programs. (11 2016). [4] Rodinia Benchmarks. [n.d.]. http://lava.cs.virginia.edu/Rodinia/download.htm. [Online; accessed 25-Apr-2022]. [5] Shuai Che, Michael Boyer, Jiayuan Meng, David Tarjan, Jeremy W. Sheaffer, Sang- Ha Lee, and Kevin Skadron. 2009. Rodinia: A benchmark suite for heterogeneous computing. In 2009 IEEE International Symposium on Workload Characterization (IISWC). 44–54. https://doi.org/10.1109/IISWC.2009.5306797 [6] Chris Cummins, Pavlos Petoumenos, Zheng Wang, and Hugh Leather. 2017. Synthesizing benchmarks for predictive modeling. In2017 IEEE/ACM International Symposium on Code Generation and Optimization (CGO) . 86–99. https://doi.org/ 10.1109/CGO.2017.7863731 [7] Chris Cummins, Bram Wasti, Jiadong Guo, Brandon Cui, Jason Ansel, Sahir Gomez, Somya Jain, Jia Liu, Olivier Teytaud, Benoit Steiner, Yuandong Tian, and Hugh Leather. 2021. CompilerGym: Robust, Performant Compiler Optimization Environments for AI Research. arXiv:2109.08267 [cs.PL] [8] Anderson Faustino da Silva, Bruno Conde Kind, José Wesley de Souza Magalhães, Jerônimo Nunes Rocha, Breno Campos Ferreira Guimarães, and Fernando Magno Quinão Pereira. 2021. ANGHABENCH: A Suite with One Million Compilable C Benchmarks for Code-Size Reduction. In2021 IEEE/ACM International Symposium on Code Generation and Optimization (CGO) . 378–390. https://doi.org/10.1109/ CGO51591.2021.9370322 [9] Sander de Bruin, Vadim Liventsev, and Milan Petković. 2021. Autoencoders as Tools for Program Synthesis. arXiv:2108.07129 [cs.AI] [10] Jia Deng, Wei Dong, Richard Socher, Li-Jia Li, Kai Li, and Li Fei-Fei. 2009. Im- ageNet: A large-scale hierarchical image database. In 2009 IEEE Conference on Computer Vision and Pattern Recognition . 248–255. https://doi.org/10.1109/CVPR. 2009.5206848 [11] Jacob Devlin, Ming-Wei Chang, Kenton Lee, and Kristina Toutanova. 2019. BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. In NAACL. [12] Jacob Devlin, Jonathan Uesato, Surya Bhupatiraju, Rishabh Singh, Abdel-rahman Mohamed, and Pushmeet Kohli. 2017. RobustFill: Neural Program Learning under Noisy I/O. In Proceedings of the 34th International Conference on Machine Learning - Volume 70 (Sydney, NSW, Australia)(ICML’17). JMLR.org, 990–998. [13] Zhangyin Feng, Daya Guo, Duyu Tang, Nan Duan, Xiaocheng Feng, Ming Gong, Linjun Shou, Bing Qin, Ting Liu, Daxin Jiang, and Ming Zhou. 2020. CodeBERT: A Pre-Trained Model for Programming and Natural Languages. arXiv:2002.08155 [cs.CL] [14] Grigori Fursin and Olivier Temam. 2011. Collective Optimization: A Practical Collaborative Approach. ACM Trans. Archit. Code Optim. 7, 4, Article 20 (dec 2011), 29 pages. https://doi.org/10.1145/1880043.1880047 [15] GitHub. [n.d.]. https://docs.github.com/en/rest. [Online; accessed 25-Apr-2022]. [16] Andrés Goens, Alexander Brauckmann, Sebastian Ertel, Chris Cummins, Hugh Leather, and Jeronimo Castrillon. 2019. A Case Study on Machine Learning for Synthesizing Benchmarks . Association for Computing Machinery, New York, NY, USA, 38–46. https://doi.org/10.1145/3315508.3329976 [17] Google. [n.d.]. https://cloud.google.com/bigquery. [Online; accessed 25-Apr- 2022]. [18] Dominik Grewe, Zheng Wang, and Michael F. P. O’Boyle. 2013. Portable mapping of data parallel programs to OpenCL for heterogeneous systems. InProceedings of the 2013 IEEE/ACM International Symposium on Code Generation and Optimization (CGO). 1–10. https://doi.org/10.1109/CGO.2013.6494993 [19] Kavi Gupta, Peter Christensen, Xinyun Chen, and Dawn Song. 2020. Synthesize, Execute and Debug: Learning to Repair for Neural Program Synthesis. [20] Ameer Haj-Ali, Qijing (Jenny) Huang, John Xiang, William Moses, Krste Asanovic, John Wawrzynek, and Ion Stoica. 2020. AutoPhase: Juggling HLS Phase Orderings in Random Forests with Deep Reinforcement Learning. In Proceedings of Machine Learning and Systems , I. Dhillon, D. Papailiopoulos, and V. Sze (Eds.), Vol. 2. 70–81. https://proceedings.mlsys.org/paper/2020/file/ 4e732ced3463d06de0ca9a15b6153677-Paper.pdf [21] Farah Hariri and August Shi. 2018. SRCIROR: A Toolset for Mutation Testing of C Source Code and LLVM Intermediate Representation. In 2018 33rd IEEE/ACM International Conference on Automated Software Engineering (ASE) . 860–863. https: //doi.org/10.1145/3238147.3240482 [22] John L. Henning. 2006. SPEC CPU2006 Benchmark Descriptions. SIGARCH Comput. Archit. News 34, 4 (sep 2006), 1–17. https://doi.org/10.1145/1186736. 1186737 [23] Sepp Hochreiter and Jürgen Schmidhuber. 1997. Long Short-Term Memory. Neural Comput. 9, 8 (nov 1997), 1735–1780. https://doi.org/10.1162/neco.1997.9. 8.1735 [24] Aditya Kanade, Petros Maniatis, Gogul Balakrishnan, and Kensen Shi. 2020. Learning and Evaluating Contextual Embedding of Source Code. arXiv:2001.00059 [cs.SE] [25] Chris Lattner and Vikram Adve. 2004. LLVM: A Compilation Framework for Lifelong Program Analysis and Transformation. In CGO. San Jose, CA, USA, 75–88. [26] Yann LeCun, Y. Bengio, and Geoffrey Hinton. 2015. Deep Learning. Nature 521 (05 2015), 436–44. https://doi.org/10.1038/nature14539 [27] Leandro T. C. Melo, Rodrigo G. Ribeiro, Breno C. F. Guimarães, and Fernando Magno Quintão Pereira. 2020. Type Inference for C: Applications to the Static Analysis of Incomplete Programs. ACM Trans. Program. Lang. Syst. 42, 3, Article 15 (nov 2020), 71 pages. https://doi.org/10.1145/3421472 [28] Maxwell Nye, Luke B. Hewitt, Joshua B. Tenenbaum, and Armando Solar-Lezama. 2019. Learning to Infer Program Sketches. In ICML. [29] Adam Paszke, Sam Gross, Francisco Massa, Adam Lerer, James Bradbury, Gregory Chanan, Trevor Killeen, Zeming Lin, Natalia Gimelshein, Luca Antiga, Alban Des- maison, Andreas Kopf, Edward Yang, Zachary DeVito, Martin Raison, Alykhan Tejani, Sasank Chilamkurthy, Benoit Steiner, Lu Fang, Junjie Bai, and Soumith Chintala. 2019. PyTorch: An Imperative Style, High-Performance Deep Learning Library. In Advances in Neural Information Processing Systems 32 , H. Wallach, H. Larochelle, A. Beygelzimer, F. d'Alché-Buc, E. Fox, and R. Garnett (Eds.). Cur- ran Associates, Inc., 8024–8035. http://papers.neurips.cc/paper/9015-pytorch- an-imperative-style-high-performance-deep-learning-library.pdf [30] Matthew Peters, Mark Neumann, Mohit Iyyer, Matt Gardner, Christopher Clark, Kenton Lee, and Luke Zettlemoyer. 2018. Deep contextualized word representa- tions. (02 2018). [31] Alec Radford and Karthik Narasimhan. 2018. Improving Language Understanding by Generative Pre-Training. [32] H. S. Seung, M. Opper, and H. Sompolinsky. 1992. Query by Committee. InProceed- ings of the Fifth Annual Workshop on Computational Learning Theory (Pittsburgh, Pennsylvania, USA) (COLT ’92) . Association for Computing Machinery, New York, NY, USA, 287–294. https://doi.org/10.1145/130385.130417 [33] OpenCL specification. [n.d.]. https://www.khronos.org/registry/OpenCL/specs/ 3.0-unified/html/OpenCL_C.html. [Online; accessed 25-Apr-2022]. [34] John E. Stone, David Gohara, and Guochun Shi. 2010. OpenCL: A Parallel Pro- gramming Standard for Heterogeneous Computing Systems.Computing in Science Engineering 12, 3 (2010), 66–73. https://doi.org/10.1109/MCSE.2010.69 [35] Kai Sheng Tai, Richard Socher, and Christopher D. Manning. 2015. Improved Semantic Representations From Tree-Structured Long Short-Term Memory Net- works. In Proceedings of the 53rd Annual Meeting of the Association for Computa- tional Linguistics and the 7th International Joint Conference on Natural Language Processing (Volume 1: Long Papers) . Association for Computational Linguistics, Beijing, China, 1556–1566. https://doi.org/10.3115/v1/P15-1150 [36] Zheng Wang and Michael O’Boyle. 2018. Machine Learning in Compiler Opti- mization. Proc. IEEE 106, 11 (2018), 1879–1901. https://doi.org/10.1109/JPROC. 2018.2817118 [37] Xuejun Yang, Yang Chen, Eric Eide, and John Regehr. 2011. Finding and Un- derstanding Bugs in C Compilers. In Proceedings of the 32nd ACM SIGPLAN Conference on Programming Language Design and Implementation (San Jose, Cali- fornia, USA) (PLDI ’11) . Association for Computing Machinery, New York, NY, USA, 283–294. https://doi.org/10.1145/1993498.1993532 Absinthe: Learning an Analytical Performance Model to Fuse and Tile Stencil Codes in One Shot Tobias Gysi Department of Computer Science ETH Zurich, Switzerland tobias.gysi@inf.ethz.ch Tobias Grosser Department of Computer Science ETH Zurich, Switzerland tobias.grosser@inf.ethz.ch Torsten Hoefler Department of Computer Science ETH Zurich, Switzerland htor@inf.ethz.ch Abstract—Expensive data movement makes the optimal target- specific selection of data-locality transformations essential. Loop fusion and tiling are the most important data-locality trans- formations. Their optimal selection is hard since good tile size choices inherently depend on the fusion choices and vice versa. Existing approaches avoid this difficulty by optimizing independent analytical models or by reverting to heuristics. Absinthe formulates the first unified linear optimization problem to derive single shot fusion and tile size decisions for stencil codes. At the core of our optimization problem, we place a learned analytic performance model that captures the characteristics of the target system. The tuned application kernels demonstrate excellent performance within 10% of exhaustively auto-tuned versions and up to 74% faster than the results of independent optimization with max fusion heuristic and Absinthe tile size selection. While the full search space is non-linear , bounding it to relevant solutions enables the efficient exploration of the exponential search space using linear solvers. As a result, the tuning of our application kernels takes less than one minute. Our approach thus establishes the foundations for next-generation compilers, which exploit empirical information to guide target- specific code transformations. Index T erms—stencils, performance model, data-locality I. I NTRODUCTION The cost of data movement in terms of energy and time has long exceeded the cost of computation. Thus, data locality recently became the most important optimization target for performance engineers [1]. Today, most programmers either rely on the compilation toolchain or manually optimize data locality by tiling and fusing loops. Manual loop optimizations are tedious and require a high porting effort to exploit different architectures efficiently because tiling and fusion parameters need to be adjusted for each target system. V arious frameworks such as Halide [2] and Polymage [3] focus their tuning on this parameter selection, but they either apply heuristics or optimize tiling and fusion separately to control the exponen- tial search space. However, fusion and tiling are inherently linked—for optimizing one, one needs to assume a specific configuration for the other. For example, the optimal tile size depends on the memory footprint of the loop, which changes with fusion. This missing modularity of the problem requires us to consider tiling and fusion in tandem. Stencil computations on regular grids are ubiquitous in scientific computing applications such as climate modeling [4], seismic imaging [5], and electromagnetic simulations [6]. absinthe 64x4x3 64x4x5 20 1 3 4 6 5 7 8 unfused tiled 64x64x1 20 1 3 4 6 5 7 8 auto-tuning 64x4x1 64x4x4 model prediction [ms] measured execution time [ms] 1.080.730.67 0.94 0.62 0.58 -6.5% 20 1 3 4 6 5 7 8 Fig. 1: Absinthe optimization example In this work, we use the COSMO atmospheric model [4], which is used in operational weather forecasting in most of Europe [7] as well as in large-scale climate modeling [8], as a motivating example. The 300′000 lines of code contain more than 16′000 loops, most of which implement single stencils. These stencils logically form complex producer- consumer relationships, calledstencil programs [9]. We select three representative COSMO stencil programs to evaluate the effectiveness of our approach. Due to the very low arithmetic intensity of every single stencil, tiling and fusion are crucial for achieving good performance for stencil programs. We show an example in Fig. 1—COSMO’s fastwaves stencil program which implements parts of the sound wave forward integration. The directed graphs show the data-flow (edges) between the stencils (nodes) of the fastwaves program. Our optimization framework,Absinthe1, uses an automatically learned performance model to guide the program optimization. The figure plots the model prediction versus the measured execution time for the tile size (annotated) and fusion (shaded shapes) choices of Absinthe compared to auto-tuning and an 1https://github.com/spcl/absinthe.git 369 2019 28th International Conference on Parallel Architectures and Compilation Techniques (PACT) 978-1-7281-3613-4/19/$31.00 ©2019 IEEE DOI 10.1109/PACT.2019.00036 target system model learner benchmarkparameters optimizer code generator C++ transfor- mations P, B 1 2 3 ILP solver stencil DSL Fig. 2: Absinthe architecture overview unfused tiled implementation. Absinthe consists of three main pieces: (1) a model learner, (2) an optimizer, and (3) a code generator. Themodel learner generates a performance model specific to each target architec- ture. The optimizer derives an integer linear program encoding the structure of the stencil program and the performance model to tune tiling and fusion together. The code generator then emits an implementation with the optimal tiling and fusion parameters returned by the integer linear programming solver. In this way, Absinthe combines automated model learning with integer linear programming to control the exponential search space and to automatically find the best configuration for each target architecture. In summary, we make the following key contributions: • A linear formulation of parametric tiling for bound tile sizes (assumed to be non-linear in general). • A linear performance model that learns the target sys- tem characteristics and enables the use of integer linear programming to explore the search space. • A single holistic optimization problem which applies the linear performance model to derive optimal fusion and tile size selection choices for stencil codes. II. B ACKGROUND The execution of stencils in succession provides plenty of opportunities for data locality improvements. A. Architecture Overview Absinthe lowers stencil programs written in a high-level domain-specific language (DSL) to efficient C++ code. An automatically learned performance model drives the selection of target system specific code transformations. Fig. 2 shows the interplay of the Absinthe components. The model learner (1) runs once for every target system to learn the model parameters. The optimizer (2) combines the model parameters with the memory access patterns of the stencil program to instantiate a target-specific performance model. An integer linear programming (ILP) solver searches the optimal data-locality transformations with respect to the performance model. The code generator (2) applies the optimal data-locality transformations to the high-level stencil program representation and generates tuned C++ code. 1 for(int x=xbeg; x<=xend; ++x) 2 for(int y=ybeg; y<=yend; ++y) 3 for(int z=zbeg; z<=zend; ++z) 4 s0(x,y,z) = 0.5 * (i0(x+1,y,z) + i0(x,y,z)); 5 for(int x=xbeg; x<=xend; ++x) 6 for(int y=ybeg; y<=yend; ++y) 7 for(int z=zbeg; z<=zend; ++z) 8 s1(x,y,z) = i1(x,y,z) * (s0(x,y+1,z) - s0(x,y-1,z)); Fig. 3: Example stencil sequence with lengthN =2 Absinthe targets three-dimensional stencil programs and optimizes them to utilize all processors of the target system, assuming exclusive system access. Our implementation has the following limitations: 1) we support only three-dimensional arrays, 2) we do not optimize the boundary conditions, and 3) we tile the codes only for one memory hierarchy level. B. Stencil Sequences A stencil is an element-wise computation with a position independent access pattern. Every stencil evaluation accesses the input arrays at fixed offsets relative to the updated output array element. We assume that every stencil writes a single array. We apply stencils to all array elements except for a constant width halo at the array boundary which prevents out- of-bounds accesses. A stencil sequence is a program formed of several subse- quent stencil applications. Fig. 3 shows an example stencil sequence with length N =2 . The short example sequence allows us to illustrate our approach with less complexity compared to the fastwaves kernel introduced in Fig. 1. C. Data-Locality Transformations Absinthe combines rectangular tiling with redundant com- putation at the tile boundaries to satisfy the data dependencies of fused stencils. This overlapped tiling [10] enables major performance improvements. The tuned fastwaves kernel shown by Fig. 1 executes 1.5× faster compared to the unfused tiled implementation variant. Loop tiling decomposes the domain into hyper-rectangular tiles of equal size. To increase the data-locality, we evaluate the stencil on the entire tile before proceeding with the next one. We thus introduce an additional outermost loop that iterates over all tiles. To support arbitrary domain sizes, we cut the tiles at the domain boundary. Loop fusion replaces the tile loops of consecutive stencils with a single tile loop that evaluates one stencil after another before proceeding with the next tile. After fusion, the data dependencies of producer-consumer stencils cross the tile boundaries. To enable the parallel tile execution, we extend the loop bounds of the producer stencils to perform redundant computation at the tile boundaries which satisfies all data dependencies locally. The combination of fusion and tiling effectively increases the spatial and temporal locality for stencils with overlapping working sets. The code generator introduces one tile loop for every group of fused stencils and allocates temporary storage 370 TABLE I: Important constants and variables constants N number of stencils in the stencil sequence Dx,D y,D z domain sizes Hx,H y,H z halo widths T number of processors C cache capacity P f ,B f fast memory peel & body parameters P b,B b slow memory peel & body base parameters P v,B v slow memory peel & body variable parameters variables gi group index nx i ,n y i ,n z i tile counts pf i ,b f i fast memory peel & body cost pb i ,b b i slow memory peel & body base cost pv i ,b v i slow memory peel & body variable cost ex+ i ,e y+ i ,e z+ i evaluation boundary widths (positive axis direction) ex− i ,e y− i ,e z− i evaluation boundary widths (negative axis direction) target system STENCILS = { S0 : 0.5 * ( i0(x+1,y,z) + i0(x,y,z)) S1 : i1(x,y,z) * ( s0(x,y+1,z) + s0(x,y-1,z)) } stencil sequence performance model fast memory slow memory data-locality transformations loop fusion loop tiling parameters Ai, Bi x, Bi y, Bi z N, Dx, Dy, Dz, T, C Pf, Bf, Pb, Bb, Pv, Bv learn analyze min t ILP Fig. 4: Absinthe ILP parameters and components to buffer intra-tile data dependencies with minimal memory footprint. III. M ODELING The optimizer automatically instantiates an integer linear program (ILP) to find good data-locality transformations. Fig. 4 shows the main components of the ILP: theparameters component captures the stencil sequence and target system properties that provide the basis for the optimization, thedata- locality transformations component defines the optimization variables that span the space of possible transformations, and the performance model component estimates the execution time for the selected code transformations. At optimization time, the ILP solver searches the code transformations with minimal estimated execution time. We present the ILP for three-dimensional stencils, but the formulation generalizes to stencils with different dimension- ality. If not mentioned otherwise, the variables are positive and integer-valued, while lowercase and uppercase identifiers distinguish optimization variables and constants, respectively. Table I lists important constants and variables. A. Stencil Sequences The optimizer requires an analysis of the stencil access patterns to instantiate the ILP shown by Fig. 4. The access patterns provide the basis to compute the data-flow and to estimate the performance of the stencil sequence. We use positive indexes to number the stencils in execution order and negative indexes to identify the input arrays. For example, the indexes[0, 1] refer to the stencils[s0,s 1] and the indexes [−1, −2] to the input arrays [i0,i 1] of the example stencil sequence shown by Fig. 3. The stencil indexes also map one-to-one to the output arrays since every stencil writes precisely one output. The resulting index space thus uniquely identifies the input and output arrays of the stencil sequence. To specify the data access patterns, we define for every stencil i the access set Ai holding (index, offset) tuples that define the array and the three-dimensional relative offset of every input element access. The access sets A0 = {(−1, (1, 0, 0)), (−1, (0, 0, 0))}, A1 = {(−2, (0, 0, 0)), (0, (0, 1, 0)), (0, (0, −1, 0))} include all accesses of the example stencils. We also compute minimal bounding boxes that contain all access offsets. To represent the bounding boxes, we define for every stencil i and dimension d the bounds set Bd i holding (index, range) tuples that specify the array and the minimal and maximal access offset along the dimension. The bounds sets Bx 0 = {(−1, (0, 1))}, By 1 = {(−2, (0, 0)), (0, (−1, 1))} contain all accesses of the example stencils along the selected dimensions. To execute the stencil sequence, we define for every di- mension d the constant domain sizeDd and the constant halo width Hd along the dimension. The domain sizes determine the stencil loop bounds, while the halo sizes together with the domain sizes specify the array allocation size. For example, we may execute the example stencils on the domain Dx =6 4,D y =6 4,D z =6 0 and select the halo widths Hx =1 ,H y =1 ,H z =0 to accommodate the transitive stencil access offsets, which results in the array allocation size66 ×66 ×60. B. Data-Locality Transformations The optimizer also defines the optimization variables that span the space of possible data-locality transformations and introduces constraints to exclude solutions that suffer from load imbalance or exceed the cache capacity. To model loop tiling, we select for every stencili ∈ [0,N ) and every dimension d the tile count nd i along the dimension from the range [ 1,D d] . For example, the tile counts nx 0 =2 ,n y 0 =2 ,n z 0 =2 split the domain of the first stencil in the example stencil sequence into two tiles along every dimension. To modelloop fusion, we select for every stencili ∈ [0,N ) the group indexgi and fuse stencils with the same group index. 371 We set the group index of the first stencil to zero and increment the group index with every additional group along the stencil sequence. For every stencil, we thus have the choice to retain or increment the group index of the preceding stencil, which spans an exponential search space in the number of stencils. For example, the group index tuples (g0,g 1) ∈{ (0, 0), (0, 1)} enumerate all possible group assignments for the example stencil sequence. The group indexes g0 =0 ,g 1 =0 assign the stencils to the same group to model fusion while the group indexes g0 =0 ,g 1 =1 assign the stencils to different groups that execute consecutively. To quantify theredundant computation, we also extend for every stencil i ∈ [0,N ) and for every dimension d the tile size with the evaluation boundary widths ed+ i and ed− i along both directions. For example, the evaluation boundary widths ey+ 0 =1 ,e y− 0 =1 extend the tile size of the first stencil to satisfy all data dependencies of the example stencil sequence locally. We define the tile sizes for every stencil, but the stencils of each group share the same tile loop and tile size. We thus enforce tile count equality for succeeding stencils with the same group index. To guaranteedata-locality, we exclude tile sizes that exceed the cache capacityC (L2 cache). To estimate the cache utiliza- tion, we multiply for every stencil group the tile size with the number of accessed arrays. This approximation optimistically models a fully associative cache with a least recently used cache replacement policy and does not consider the accesses at the tile boundaries. We thus enforce the cache utilization for a single tile to be lower than one-third of the cache capacity. This choice compensates for our optimistic cache modeling and ensures that not only the current but also the next and the previous tile executed by the same processor mostly fit the cache. As a result, the data-locality improves since the overlapping boundaries of consecutive tiles stay in cache. To guarantee parallel efficiency, we enforce a total number of tiles within 5% of an integer multiple of the number of processors T and for every dimension a tile count within2% of an integer multiple of the domain size. C. Performance Model The optimizer finally instantiates the performance model based on the stencil sequence and target system parameters shown by Fig. 4. The performance model distinguishes two cost components: (1) the peel cost models the latency and (2) the body cost models the throughput of the innermost loop executions. In other words, thepeel cost accounts for loop startup overheads – examples are the over fetch at the loop boundaries or the execution of scalar peel loops – while thebody cost models the steady-state of the loop execution. For both components, we model the memory accesses for two memory hierarchy levels: (1) the fast memory (L2 cache) and (2) theslow memory (L3 nx=ny=2 Dx=Dy=4 DxDy body domain nxny peel domain nxDy DxnyDynx y x y x y x Fig. 5: Illustration of the peel and body domain computation for domain size8×8 split into 2×2 tiles with boundary width one along the positive axis directions. cache or DDR memory). For every data element, we assume the slow memory handles the first and the fast memory all subsequent accesses during the tile execution. To estimate the execution time, the performance model multiplies the number of memory accesses with the learned model parameters. The loop startup overheads make long tiles along the innermost loop dimension more efficient. To model this effect, we distinguish the peel cost proportional to the number of innermost loop executions (peel domain) and the body cost proportional to the number of innermost loop iterations (body domain). This separation allows us to assign a higher cost to memory accesses executed during the loop startup. The two cost components and the goal to employ efficient integer linear programming solvers result in linear cost functions of the form Px +By that sum the peel costPx and the body costBy. The variables x and y denote the number of memory accesses for the peel and body domains, respectively. The learned model parameters P and B convert the memory accesses to execution times. Sec. III-D details how themodel learner determines the model parameters. The performance model combines multiple cost functions to estimate the stencil sequence execution time. To define the cost functions, we next introduce the peel and body functions that compute the weighted size of the peel and body domains, respectively. Fig. 5 shows the computation of the peel domain (left) and the body domain (right) for a simplified two-dimensional domain (middle) with all weights set to one. The peel domain counts the blue points (squares) while the body domain counts all points (squares and circles). The peel and body functions extend this computation with additional terms and factors to model our three-dimensional domain and parametric weights. a) peel function: The peel cost is proportional to the number of innermost loop executions. Without loss of gen- erality, we assume the innermost loops execute along the x-dimension, which means the number of innermost loop executions corresponds to the size of the tiles projected to the yz-plane. The product DyDz of the domain sizes is equal to the sum of the tile domains and the productsDzny i and Dynz i of the tile counts with the perpendicular domain size approximate the tile boundaries. To sum the tiles along the innermost loop 372 dimension, we multiply the terms with the tile count along the x-dimension. This approximation is exact except for the tile corners. To evaluate the peel cost, we define for every stencil i ∈ [0,N ) the peel function fp i (w, wy,w z)= nx i (DyDzw + Dzny i wy + Dynz i wz) which scales the inner domain and the boundary terms with the inner weight w and the boundary weights wy and wz, respectively. For example, we set the inner weight to one and the boundary weights to the evaluation boundary widths to count the innermost loop executions. b) body function: The body cost is proportional to the number of innermost loop iterations scaled with cost function- specific weights. The number of innermost loop iterations is equal to the sum of the tile volumes. To compute the volume of the overlapping tiles, we add the productDxDyDz of the domain sizes to the tile counts multiplied with the perpendicular domain sizes. This approximation again includes the tile domains and the tile boundaries without the tile corners. To evaluate the body cost, we define for every stencil i ∈ [0,N ) the body function fb i (w, wx,w y,w z)= DxDyDzw+DyDznx i wx+ DxDzny i wy+DxDynz i wz which scales the inner domain and the boundary terms with the inner weight w and the boundary weights wx, wy, and wz, respectively. For example, we set the inner weight to one and the boundary weights to the evaluation boundary widths to count the innermost loop iterations. The peel and body functions next allow us to define the cost functions for the two memory hierarchy levels. c) fast memory: The fast memory model counts the memory accesses to estimate the stencil execution time. We assume that every evaluation of the stencili loads the entire access set Ai and stores the result. The stencili thus performs 1+|Ai|memory accesses per evaluation. To count the memory accesses, we set for every stencili ∈ [0,N ) the weight ci =1+ |Ai| to the number of memory accesses per stencil evaluation and for every dimension d the boundary weight cd i =( 1+ |Ai|)(ed− i + ed+ i ) to the number of memory accesses per stencil evaluation scaled with the evaluation boundary widths. The multiplication reflects that the stencils are evaluated at every evaluation boundary line. We then set for every stencil i ∈ [0,N ) the peel cost pf i and the body cost bf i of the fast memory model to the products pf i = P f fp i (ci,c y i ,c z i ),b f i = Bf fb i (ci,c x i ,c y i ,c z i ) which evaluate the peel and body functions to obtain the number of memory accesses for the peel and body domains, respectively. The learned model parametersP f and Bf con- vert the memory accesses to execution times. d) slow memory: The slow memory model determines the communication volume to estimate the execution time. We observe that the memory throughput improves with the number of parallel access streams. To model this behavior, we sum two cost functions that estimate the base cost and the variable cost with respect to the number of access streams. We assume that every stencil group loads and stores an array only once. Repeated accesses of the same array hit the fast memory and are not relevant for the slow memory model. We compute the slow memory loads and stores based on the group indexes. A stencil only loads an array from slow memory if the group index of the stencil that accessed the array last differs. Otherwise, the array was already loaded to the fast memory. A stencil only stores an array to slow memory if the group index of the last stencil that accesses the array differs. Otherwise, the array is not used outside of the stencil group, and storing to slow memory is not necessary. To estimate thebase cost, we set for every stencili ∈ [0,N ) the weight mi to one if the stencil loads or stores at least one array and to zero otherwise. We also set for every dimension d the boundary weight md i = mi(ed− i + ed+ i ) to the weight times the evaluation boundary widths. We then set for every stencil i ∈ [0,N ) the peel cost pb i and the body cost bb i of the base cost to the products pb i = P bfp i (mi,m y i ,m z i ),b b i = Bbfb i (mi,m x i ,m y i ,m z i ) which evaluate the peel and body functions to obtain the number of stencil evaluations that access at least one array for the peel and body domains, respectively. The learned model parameters P b and Bb convert the stencil evaluations to execution times. To estimate the variable cost , we set for every stencil i ∈ [0,N ) the weight si to the number of accessed arrays and for every dimension d the boundary weights sd i to the sum of the array access boundary widths along the dimension. We consider only arrays and boundary lines that have not been accessed by a preceding stencil of the same stencil group. To compute access boundary widths, we extend for every data dependency (j, (B−,B +)) ∈B d i the evaluation boundary widths with the access bounds B− and B+. We then set for every stencil i ∈ [0,N ) the peel cost pv i and the body costbv i of the variable cost to the products pv i = P vfp i (si,s y i ,s z i ),b v i = Bvfb i (si,s x i ,s y i ,s z i ) which evaluate the peel and body functions to obtain the number of access streams for the peel and body domains, respectively. The learned model parametersP v and Bv convert the access streams to execution times. The slow memory model finally sums thebase cost and the variable cost to estimate the execution time. To estimate the overall stencil execution time, we assume that the fast memory and the slow memory accesses overlap. We thus compute for every stencil the maximumpeel cost and 373 the maximum body cost of the two memory hierarchy levels. The sum ∑ N−1 i=0 max(pf i ,p b i + pv i )+m a x (bf i ,b b i + bv i ) accumulates the individual stencil execution times to obtain the execution time of the entire stencil sequence. The term ∑ N−1 i=0 2 ·3(Bb + Bv)nx i ny i nz i emulates the slow memory access cost to load the two pre- computed tile loop bounds for all three dimensions to account for the tile execution overheads. We include this term in the estimated execution time to favor implementation variants with fewer tiles. Together, the estimated execution time and the tile execution overheads define the objective function of the integer linear program. D. Learning the Performance Model The model learner adapts the performance model param- eters to the performance characteristics of the target system. To learn the parameters, we implemented training stencils that either stress the slow or the fast memory and measure their execution time for different tile sizes. We then compute the model parameters using least absolute deviations (LAD) [11] regression, which compared to least squares regression has better outlier robustness. As the performance depends on the tile shape, we bench- mark the training stencils with tile sizes ranging from 10 to 80 elements along thex-dimension and from1 to 55 elements along the other dimensions. We exclude tiles with a volume below 500 or above 2000 elements to ensure that the tiles fit the fast memory (L2 cache). In total, we run 103 tile size configurations. When learning the fast memory model, the fast memory accesses have to dominate the execution times of the training stencils. We used three training stencils that access 12, 16, and 20 array positions. We always connect nine identical stencils that access the same input array to one training sequence. The repeated accesses of the same input array guarantee that the fast memory accesses dominate the execution time. We benchmark the three training sequences for all tile size configurations. For every run r ∈ [0,R ), we collect the measured execution time tr and compute the number of fast memory accesses xr and yr for the peel and body domain, respectively. The LAD regression (P f ,B f ) = argmin (P,B)∈R2 ∑ r∈[0,R) |(Px r + Byr) −tr| then selects the fast memory model parameters P f and Bf that minimize the L1-norm of the prediction error. When learning the slow memory model, the slow memory accesses have to dominate the execution times. We used nine training stencils that access 1, 2, or 3 input arrays with access boundary width 0, 1, or 2. The stencils access the input arrays at three diagonal offsets to avoid unnecessary fast memory accesses. We always connect nine identical stencils that access different input and output arrays to one training sequence. The many loaded and stored arrays guarantee that the slow memory accesses dominate the execution time. We benchmark the nine training sequences for all tile size configurations. For every run r ∈ [0,R ), we collect the mea- sured execution time tr. To learn the base cost, we compute the number of stencil evaluationsxr and yr that perform slow memory accesses for the peel and body domain, respectively. To learn the variable cost, we compute the number of slow memory accesses ur and vr for the peel and body domain, respectively. The LAD regression (P b,B b,P v,B v) = argmin (P ′,B′,P ′′,B′′)∈R4 ∑ r∈[0,R) |(P ′xr+ B′yr + P ′′ur+B′′vr) −tr| then selects the slow memory model parameters P b, Bb, P v, and Bv that minimize the L1-norm of the prediction error. All training sequences are synthetic and differ from the application kernels tuned in Sec. V -D. IV . OPTIMIZA TION The number of possible data-locality transformations de- fined in Sec. III-B makes the manual tuning of stencil pro- grams difficult. To automate the process, we could exhaus- tively search for the optimal data-locality transformations according to the performance model introduced in Sec. III-C. However, for stencil sequences of lengthN the search space contains O(2N ND xDyDz) implementation variants which decompose into 2N fusion choices multiplied with up to N stencil groups and DxDyDz tile size choices. This large search space motivates advanced optimization methods. To explore the search space, we rely on the well established mixed-integer linear programming (MILP) approach, which finds or approximates the optimal solution within some pre- defined objective function gap. The optimizer translates the performance model and the space of data-locality transforma- tions to an MILP that defines the optimization problem. We next detail the automatic translation of the performance model to linear constraints. A. Linearizing Multiplications The performance model multiplies the tile count variables with other variables. Linear programs cannot directly express the product of two integer variables. An implementation trick [12] nevertheless allows us to multiply two variablesx and y with known upper bounds X and Y . We first observe that the product of the binary variable b and the variable x with known upper bound X translates to three constraints. The constraint0 ≤ p ≤ x limits the product p to the range [0,x ], while the constraints p −Xb ≤ 0 and p −x −Xb ≥− X force the product to zero ifb is zero and to x otherwise. To express the product of two variables x and y with the known upper bounds X and Y , we next encode the variable y with the sum y = ∑ ⌊log2(Y )⌋ i=0 2iyi 374 where the binary variables yi represent the digits of y. Then the product p = xy corresponds to the sum p = ∑ ⌊log2(Y )⌋ i=0 2ixyi of the binary products xyi scaled with the power of two associated with the respective digit. All binary products are translated to the constraints introduced before. The optimizer implements the performance model by intro- ducing binary representations for all tile count variables and lowers the products as shown above. This solution works since we know that for every dimensiond the range [1,D d] limits the tile count variables. B. Modeling Stencil Groups The number of stencil groups is an optimization variable not known during the generation of the optimization problem. Allocating one variable per stencil group to store group prop- erties such as the tile count is thus not possible. Instead, we model stencil group properties with the help of stencil specific variables. At optimization time, the group index variables of Sec. III-B allow us to compute stencil group properties and to assign them to all stencil specific variables of the group. The group indexes increase monotonically along the stencil sequence. The constraint g0 =0 sets the group index of the first stencil to zero. To limit the remaining group indexes, we define for every stencili ∈ [0,N −1) the constraint 0 ≤ gi+1 −gi ≤ 1, which sets the group index difference of succeeding stencils to zero or one for fusion and no fusion, respectively. With the help of the group indexes, we define constraints that apply to the stencil groups. For example, the tile counts have to be equal within the stencil group. To enforce equality, we define for every stencil i ∈ [0,N −1) and for every dimension d the constraints nd i+1 −nd i + Dd(gi+1 −gi) ≥ 0, nd i+1 −nd i −Dd(gi+1 −gi) ≤ 0 which limit the tile count difference to zero if the stencils have the same group index. Otherwise, the group index difference gi+1 −gi is positive since the indexes increase along the stencil sequence. Then the group index difference multiplied with the upper bound Dd for the tile count difference nd i+1 − nd i disables the constraints for all possible tile count assignments. The upper bound follows from the observation that the tile counts range from one to the domain sizeDd. The optimizer uses the group index variables to model the tile counts, the cache utilization, and the number of slow memory accesses. V. EV ALUA TION To validate our approach, we learn the performance model for three target systems and compare application kernels tuned with Absinthe to heuristically tuned, hand-tuned, and auto- tuned implementation variants. 1 STENCILS = { 2 "s0":"auto res = 0.5*(i0(x+1,y,z)+i0(x,y,z));", 3 "s1":"auto res = i1(x,y,z)*(s0(x,y+1,z)+s0(x,y-1,z));"} Fig. 6: Absinthe version of the example stencil sequence 1 #pragma omp parallel for schedule(static) 2 for(int i d x=0 ;i d x<1 * 3 * 12; ++idx) { 3 // views of the input and output arrays 4 loop_info l = _tiles_group0[idx]; 5 array_view_3d i1(&__i1(l.xbeg, l.ybeg, l.zbeg)); 6 array_view_3d i0(&__i0(l.xbeg, l.ybeg, l.zbeg)); 7 array_view_3d s1(&__s1(l.xbeg, l.ybeg, l.zbeg)); 8 // stack allocated temporary arrays 9 tarray0_3d ___s0; 10 tarray0_view_3d s0(&___s0(HX, HY, HZ)); 11 12 { // apply s0 stencil 13 int xbeg = _loops_s0[idx].xbeg; 14 int xend = _loops_s0[idx].xend; 15 int ybeg = _loops_s0[idx] ybeg; 16 int yend = _loops_s0[idx].yend; 17 int zbeg = _loops_s0[idx].zbeg; 18 int zend = _loops_s0[idx].zend; 19 for(int z = zbeg; z < zend; ++z) 20 for(int y = ybeg; y < yend; ++y) 21 #pragma omp simd 22 for(int x = xbeg; x < xend; ++x) { 23 auto res = 0.5 (i0(x+1,y,z) + i0(x,y,z)); 24 s0(x,y,z) = res; 25 }} 26 27 { // apply s1 stencil 28 int xbeg = _loops_s1[idx].xbeg; 29 int xend = _loops_s1[idx].xend; 30 int ybeg = _loops_s1[idx] ybeg; 31 int yend = _loops_s1[idx].yend; 32 int zbeg = _loops_s1[idx].zbeg; 33 int zend = _loops_s1[idx].zend; 34 for(int z = zbeg; z < zend; ++z) 35 for(int y = ybeg; y < yend; ++y) 36 #pragma omp simd 37 for(int x = xbeg; x < xend; ++x) { 38 auto res = i1(x,y,z) * (s0(x,y+1,z) + s0(x,y-1,z)); 39 s1(x,y,z) = res; 40 }} 41 } Fig. 7: Optimized code for the example stencil sequence A. Setup & Methodology The target systems feature Xeon E5-2695 v4, Xeon Phi 7210, and Power8NVL sockets. We configure the Xeon Phi sockets with two NUMA domains, each of them with 32 processors and three DDR channels, and run the experiments on one of the two NUMA domains. We optimize the linear programs with CPLEX 12.6.3 and compile the generated C++ codes with GCC 5.3 on the Xeon and Xeon Phi systems and with GCC 5.4 on the Power system. To perform the experiments, we set the domain size to64× 64 × 60 elements with 3 × 3 × 3 halo elements similar to the COSMO [4] production configuration. All experiments are performed using double-precision floating-point numbers. We set the number of processors to the available coresT = 18, T =3 2, and T =1 0 for the Xeon, Xeon Phi, and Power systems, respectively. To measure the execution time, we repeat every experiment 64 times and discard the first16 measurements to warmup the 375 p=12 p=16 p=20 Pf = 2e-07 Bf = 1.8e-080.00 0.05 0.10 20 40 60 80 x execution time [ms] fast memory (Xeon) p=12 p=16 p=20 Pf = 4.4e-07 Bf = 1.9e-080.00 0.10 0.20 0.30 20 40 60 80 x execution time [ms] fast memory (Xeon Phi) p=12 p=16 p=20 Pf = 1.6e-07 Bf = 1.7e-080.00 0.02 0.04 0.06 20 40 60 80 x execution time [ms] fast memory (Power) i=1,b=1 i=2,b=1 i=3,b=1 Pb = 1.7e-06 Bb = 7.5e-08 Pv = 8.9e-07 Bv = 6.5e-080.00 0.05 0.10 0.15 0.20 20 40 60 80 x execution time [ms] slow memory (Xeon) i=1,b=1 i=2,b=1 i=3,b=1 Pb = 3.4e-06 Bb = 2.6e-07 Pv = 7.9e-07 Bv = 1.8e-070.00 0.25 0.50 0.75 20 40 60 80 x execution time [ms] slow memory (Xeon Phi) i=1,b=1 i=2,b=1 i=3,b=1 Pb = 4.7e-06 Bb = 2.4e-07 Pv = 1.8e-07 Bv = 3.7e-080.00 0.03 0.06 0.09 20 40 60 80 x execution time [ms] slow memory (Power) Fig. 8: Measured (polygons) and estimated (lines) execution times for the fast memory (p=positions) and slow memory (i=input arrays and b=boundary width) training stencils and variable tile sizes along thex-dimension. memory hierarchy. Before every run, except when learning the fast memory model, we flush the L1 and L2 caches with dummy data. As we assume exclusive system access, we run one thread per processor. We time only the stencil executions, which excludes the initialization logic and the boundary con- ditions. All plots show median values and nonparametric95% confidence intervals [13] to visualize the distribution of the measurements. B. Implementation Absinthe provides a high-level stencil DSL to implement stencil programs. Fig. 6 and Fig. 7 show the DSL version and the generated code for the example stencil sequence introduced in Sec. II-B, respectively. Absinthe parses the DSL to extract the accesses patterns. Based on this analysis, the optimizer derives the integer linear program and determines the optimal solution using the CPLEX solver [14]. After the optimization, the code generator emits C++ code that implements the fusion and tile size choices of the optimal solution. The code generator performs overlapped tiling [10] with one tiling hierarchy level and periodic boundary conditions. In addition to the stencil sequence, we also generate the boilerplate necessary to execute, benchmark, and verify the stencil sequence. The verification compares the results of the parallel implementation to naive sequential code. The code generator utilizes the Jinja2 template engine [15] to specialize a generic stencil sequence template with the program-specific logic. C. Learning the Target Systems Absinthe learns the performance model parameters once for every target system and then tunes all stencil programs using the same parameter set. Sec. III-D discusses the performance model learning. We next evaluate the quality of the learned model parameters. To improve the noise robustness, we use all 48 measure- ments per experiment when learning the model parameters using LAD regression [11]. We use the median of the repeated measurements when computing the R2 values. Fig. 8 compares for the tile sizes 5 × 5 × x the measured execution times of the training stencils to the learned fast memory and slow memory models. We observe that for the shown tile sizes, the execution times increase almost linearly with the tile size along thex-dimension with model predictions close to the measured execution times of the training stencils. The annotations mark the different training stencils. For ex- ample, the annotationp =1 2refers to the training stencil that accesses twelve positions, and the annotation i =3 ,b =1 refers to the training stencil that accesses three input arrays with boundary width one. 376 absinthe hand min max (74.0%) auto-tuning (-6.5%)0.5 0.7 0.9 1.1 1.3 0.5 0.7 0.9 1.1 1.3 estimated time [ms] measured time [ms] fastwaves (Xeon) absinthe hand min max auto-tuning (-0.8%) 0.4 0.8 1.2 1.6 0.4 0.8 1.2 1.6 estimated time [ms] measured time [ms] diusion (Xeon) absinthehand minmax auto-tuning (-3.4%) 0.3 0.4 0.5 0.6 0.7 0.8 0.3 0.4 0.5 0.6 0.7 0.8 estimated time [ms] measured time [ms] advection (Xeon) absinthe hand min max auto-tuning (-0.7%) 1.5 2.0 2.5 1.5 2.0 2.5 estimated time [ms] measured time [ms] fastwaves (Xeon Phi) absinthehand min max auto-tuning (-7.8%)1.0 2.0 3.0 4.0 1.0 2.0 3.0 4.0 estimated time [ms] measured time [ms] diusion (Xeon Phi) absinthe hand min max auto-tuning (-7.1%) 1.0 1.5 2.0 1.0 1.5 2.0 estimated time [ms] measured time [ms] advection (Xeon Phi) absinthe hand min max auto-tuning (-6.1%) 0.6 0.8 1.0 1.2 0.6 0.8 1.0 1.2 estimated time [ms] measured time [ms] fastwaves (Power) absinthe hand min max auto-tuning (-2.5%)0.4 0.8 1.2 1.6 0.4 0.8 1.2 1.6 estimated time [ms] measured time [ms] diusion (Power) absinthe hand min max auto-tuning (-1.7%) 0.8 1.2 1.6 0.8 1.2 1.6 estimated time [ms] measured time [ms] advection (Power) Fig. 9: Measured and estimated execution times for the optimal (triangle), selected (squares), and random (dots) implementation variants of the fastwaves (N =9 ), diffusion (N =1 6), and advection (N =8 ) kernels. The R2 values of 0.87, 0.95, and 0.94 for the fast memory model and of0.96, 0.96, and 0.90 for the slow memory model confirm the quality of the learned model parameters for the Xeon, Xeon Phi, and Power systems, respectively. D. Tuning the Application Kernels Existing benchmark suites such as PolyBench [16] often contain stencil programs that iterate only one stencil instead of multiple different stencils. To evaluate the quality of our fusion and tile size selection choices, we thus implement three stencil sequences from the COSMO atmospheric model [4]. These real-world benchmark kernels contain one-, two-, and three- dimensional stencils from first to fifth order. The fastwaves kernel consists of nine stencils that compute the pressure gradi- ent, update the horizontal wind speeds, and compute the wind divergence. The diffusion kernel consists of sixteen stencils that update the pressure and the wind speeds. The advection kernel consists of eight stencils that transport the horizontal wind speeds. The two-dimensional advection and diffusion stencils access only neighbor elements in the horizontal xy- plane, while the fastwaves stencils perform three-dimensional accesses. To perform the experiments, we adapt the COSMO stencils 377 to match the current implementation of our code generator, which supports only three-dimensional arrays and periodic boundary conditions. We thus replace the original boundary conditions and remove accesses to lower-dimensional arrays. Fig. 9 shows the performance of Absinthe for all application kernels and target systems. We compare the measured and estimated execution times of the optimal solution found by Absinthe to selected and random implementation variants with group index and tile size constraints. Data points close to the diagonal imply good model prediction. The dashed lines delimit the region with 20% prediction error. The timings include the stencil computation without boundary conditions. Additionally, we add the following selected implementation variants: the min and max heuristics combine minimal and maximal fusion with the Absinthe tile size selection, the hand approach reproduces the hand-tuned fusion and tile size choices of the COSMO production code, and theauto-tuning approach combines tile size auto-tuning with the Absinthe fusion choices. As the hand and auto-tuning variants may violate the cache size or load imbalance constraints, their estimated execution times are possibly invalid. The optimal solutions for the three application kernels con- tain at most four stencil groups. To sample random implemen- tation variants, we select20 random group index assignments with at most four groups and repeat the optimization with constraints that fix the group indexes. To examine different tile sizes, we also introduce tile size constraints that enforce smaller or larger tiles along one dimension. In total, we sample 60 random implementation variants. The auto-tuning exhaustively searches for every stencil group the tile sizes1, 2, 4, 12, 30, and 60 in the z-dimension and the powers of two in thexy-plane. The tuning of isolated stencil groups does not consider the cache reuse of consecutive stencil groups. However, the approach circumvents the joint evaluation of all stencil group tile size combinations. We use the Absinthe fusion strategy to avoid auto-tuning the exponential fusion search space. a) fastwaves: The optimal solution for all target systems splits the fastwaves kernel into two groups (Fig. 1 shows the optimal solution for the Xeon system). The tile shapes reflect the three-dimensional access patterns detailed in Fig. 10. b) diffusion: The optimal solutions split the diffusion kernel into two, one, and four groups of equal sizes with tile size 64×13×1, 64×16×1, and64×32×1 for the Xeon, Xeon Phi, and Power systems, respectively. These choices reflect the two-dimensional access pattern of the stencils and the different L2 cache capacities. Most implementation variants perform better than expected. We attribute this bias to the peel cost of the slow memory model, which do not consider the cache reuse of consecutive innermost loop executions that span the full domain. c) advection: The optimal solution of the advection kernel fuses all stencils with tile size64 ×16 ×1, 64 ×32 ×1, and 64 ×32 ×1 for the Xeon, Xeon Phi, and Power systems, respectively. The fast memory model dominates the predicted execution time of the compute-intensive seven-point stencils. j+1 k+1 j+1,k+1 i+1 k+1 i+1,k+1 k-1 k+1 i+1 i+1j+1 j+1 j+1 i+1 j+1 i+1 k-1k-1 i-1j-1 i-1 k+1 i-1,k+1 j-1 k+1 j-1,k+1 j-1 i-1 input temp output arrays: example: y(i,j,k) = x(i,j,k) + x(i+1,j,k); i+1x y Fig. 10: Data-flow graph of the fastwaves kernel. All edges are annotated with the non-center access offsets that the stencils read in addition to the center position (i,j,k). Especially for the Xeon Phi and Power systems, the fast memory model tends to underestimate the measured execution times. For example, since the cache accesses may not fully overlap with the actual stencil computation. The auto-tuned versions of the fastwaves, diffusion, and advection kernels perform 6.5%, 0.8%, and 3.4% faster than Absinthe for the Xeon system, 0.7%, 7.8%, and 7.1% faster than Absinthe for the Xeon Phi system, and6.1%, 2.5%, and 1.7% faster than Absinthe for the Power system, respectively. The small performance penalty compared to the much slower auto-tuning and the relative agreement of estimated and mea- sured execution times demonstrate the effectiveness of our approach for different stencils and hardware architectures. The hand-tuned kernels perform well, but the manual opti- mization of large codes is tedious and time-consuming. The combination of fusion heuristics with Absinthe demonstrates the challenge of independent fusion and tile size selection. The auto-tuning approach always works best since it does not depend on the performance model assumptions. For ex- ample, the auto-tuned tile sizes violate the cache capacity constraints of the Power system, which means tiles fitting the L2 cache are not optimal for this architecture. Auto-tuning generates 277 implementation variants for every stencil group, which on the Xeon system results in40 minutes search time for the diffusion kernel. Extending the auto-tuning to the215 fusion choices increases the search time beyond10′000 hours. Absinthe explores the full search space in40 seconds. 378 1.66x 1.29x 1x 2.03x 3.7x 1x 1.4x 1.06x1x 0 10 20 fastwaves advection di usion execution time [ms] Absinthe Halide Polymage Fig. 11: Execution times of the Absinthe, Halide, and Poly- mage tuned application kernels for domain size256×256×60 on the Xeon system (slowdowns relative to Absinthe). E. Comparison with Halide and Polymage To compare Absinthe, we implement the application kernels with Polymage [3] (git:a8a101b) and Halide [2] (git:3af2386). We optimize the stencil sequences with the built-in auto- schedulers [17], [18], compile the Absinthe and Polymage kernels with GCC 5.3, and adapt the scheduling parameters to match the processor count of the Xeon system. Fig. 11 compares the execution times for the Absinthe, Polymage, and Halide tuned application kernels. We set the domain size to 256 × 256 × 60 elements since Halide and Polymage do not perform well for small domains. Absinthe and Polymage apply the same code transformations and use the same compiler, which makes the results comparable. Halide compiles with LL VM and performs loop reordering and stencil inlining, which reduces the significance of the results. Absinthe performs best for all kernels, which emphasizes the quality of the fusion and tile size selection choices. VI. R ELA TED WORK Tile size selection is a well-researched topic with two main directions: purely analytic approaches [19], [20], [21], [22], [23], [24], [25], [26], [27], [28] and empirical approaches [29], [30], [31], [32] that search different configurations for optimal performance. Y uki et al. [33] learn machine-specific static tile size selection models. Artificial neuronal networks are also effective for both instruction throughput prediction [34] and tile size selection [35]. All of these works regard tile size selection as a problem that must be solved after having already committed to a certain loop structure. D. Cociorva et al. [36] observe that program scheduling and tile size selection are intertwined and propose a dynamic programming based approach for combined scheduling and tile size selection specific for tensor sequences. Their work does not consider stencil computations. Quasem and Kennedy [37] propose a model guided empirical approach for loop fusion and tiling. Beaugnon et al. [38] also combine analytical mod- eling and empirical search space exploration. They present an analytical model to compute a lower bound for the execution time of partially-specified program variants that allows them to prune the search space early-on. None of these works provide a linear programming formulation. There exist several approaches for generating code for iterative stencils. Patus [39] is a code generator for iterative stencils on CPUs and GPUs. Henretty et al. [40] introduced a code generator for iterative multi-statement stencils that implements the DLT [41] data layout transformation. Both code generators rely on tile size auto-tuning. Pochoir [42] is an iterative stencil compiler that uses cache-oblivious tiling techniques to avoid the tile size selection problem. Prajapati et al. [43] manually derive tile size selection models for single statement stencils executed on GPUs. They require non- linear integer programming which takes hours to terminate and commonly does not guarantee optimal solutions. STELLA [44] is a domain-specific language for climate modeling. Halide [2] and Polymage [3] are domain-specific languages for image processing pipelines. All approaches support the optimization of stencil programs with data-locality transformations. MODESTO [9] is an analytic performance model to derive optimal fusion patterns for stencil programs based on memory bandwidth estimates. However, the model does not consider loop overheads and other metrics impor- tant for good tile size selection. For Polymage, Jangda and Bondhugula [18] employ dynamic programming to explore the space of fusion choices according to a cost function. During the optimization, a heuristic selects suitable tile sizes. For Halide, Liao et al. [45] and Mullapudi et al. [17] suggest cost functions and custom optimization strategies to perform automatic scheduling, which covers tile size selection. These solutions do not integrate the fusion and tile size selection choice in a single linear model. Absinthe thus provides the first holistic integer linear programming formulation that simulta- neously schedules stencil programs and chooses matching tile sizes. VII. C ONCLUSION Absinthe instantiates an optimization problem that evaluates a learned performance model to select target system specific data-locality transformations for stencil codes. Surprisingly six performance model parameters are sufficient to capture the relevant target system characteristics. The evaluation of the performance model is fast and requires no complex operations. We also demonstrate how to linearize the performance model for stencil codes with known domain sizes of limited range. These properties facilitate the efficient exploration of the exponential search space with the help of powerful linear solvers. Our empirical evaluation provides strong evidence that learning a target-specific performance model is a competitive alternative to auto-tuning. ACKNOWLEDGMENTS We want to thank the Swiss National Supercomputing Center (CSCS) for granting access to the computing resources. This project has received funding from the European Research Council (ERC) under the European Union’s Horizon 2020 programme (grant agreement DAPP , No. 678880), the Swiss National Science Foundation under the Ambizione programme (grant PZ00P2168016), and ARM Holdings plc and Xilinx Inc in the context of Polly Labs. 379 REFERENCES [1] D. Unat, A. Dubey, T. Hoefler, J. Shalf, M. Abraham, M. Bianco, B. L. Chamberlain, R. Cledat, H. C. Edwards, H. Finkel, K. Fuerlinger, F. Hannig, E. Jeannot, A. Kamil, J. Keasler, P . H. J. Kelly, V . Leung, H. Ltaief, N. Maruyama, C. J. Newburn, , and M. Pericas, “Trends in Data Locality Abstractions for HPC Systems,” IEEE Transactions on Parallel and Distributed Systems (TPDS), vol. 28, no. 10, Oct. 2017. [2] J. Ragan-Kelley, C. Barnes, A. Adams, S. Paris, F. Durand, and S. Amarasinghe, “Halide: a language and compiler for optimizing parallelism, locality, and recomputation in image processing pipelines,” ACM SIGPLAN Notices, vol. 48, no. 6, pp. 519–530, 2013. [3] R. T. Mullapudi, V . V asista, and U. Bondhugula, “Polymage: Automatic optimization for image processing pipelines,”SIGARCH Comput. Archit. News, vol. 43, no. 1, pp. 429–443, Mar. 2015. [4] M. Baldauf, A. Seifert, J. F¨orstner, D. Majewski, M. Raschendorfer, and T. Reinhardt, “Operational convective-scale numerical weather predic- tion with the COSMO model: Description and sensitivities,” Monthly Weather Review, vol. 139, no. 12, pp. 3887–3905, 2011. [5] G. A. McMechan, “Migration by Extrapolation of Time-Dependent Boundary V ALUES*,”Geophysical Prospecting, vol. 31, pp. 413–420, Jun. 1983. [6] A. Taflove, “Review of the formulation and applications of the finite- difference time-domain method for numerical modeling of electromag- netic wave interactions with arbitrary structures,”Wave Motion, vol. 10, no. 6, pp. 547 – 582, 1988, special Issue on Numerical Methods for Electromagnetic Wave Interactions. [7] (1998) Consortium for small-scale modeling. [Online]. Available: http://www.cosmo-model.org/ [8] O. Fuhrer, T. Chadha, T. Hoefler, G. Kwasniewski, X. Lapillonne, D. Leutwyler, D. L ¨uthi, C. Osuna, C. Sch ¨ar, T. C. Schulthess, and H. V ogt, “Near-global climate simulation at 1 km resolution: establishing a performance baseline on 4888 gpus with cosmo 5.0,” Geoscientific Model Development Discussions, vol. 2017, pp. 1–27, 2017. [9] T. Gysi, T. Grosser, and T. Hoefler, “MODESTO: Data-centric analytic optimization of complex stencil programs on heterogeneous architec- tures,” in Proceedings of the 29th ACM on International Conference on Supercomputing, ser. ICS ’15. New Y ork, NY , USA: ACM, 2015, pp. 177–186. [10] X. Zhou, J.-P . Giacalone, M. J. Garzar ´an, R. H. Kuhn, Y . Ni, and D. Padua, “Hierarchical overlapped tiling,” inProceedings of the Tenth International Symposium on Code Generation and Optimization , ser. CGO ’12. New Y ork, NY , USA: ACM, 2012, pp. 207–218. [11] B. S. Cade and J. D. Richards, “Permutation tests for least absolute deviation regression,” Biometrics, vol. 52, no. 3, pp. 886–902, 1996. [12] “ILP Part 6 Faster multiplication,” https://blog.adamfurmanek.pl/2015/ 09/26/ilp-part-6/, September 26th 2015. [13] T. Hoefler and R. Belli, “Scientific benchmarking of parallel computing systems: Twelve ways to tell the masses when reporting performance results,” in Proceedings of the International Conference for High Per- formance Computing, Networking, Storage and Analysis, ser. SC ’15. New Y ork, NY , USA: ACM, 2015, pp. 73:1–73:12. [14] IBM, IBM ILOG CPLEX Optimization Studio CPLEX User’s Manual, 2011. [15] “Welcome to Jinja2,” http://jinja.pocoo.org/docs/2.10/, 2008. [16] L.-N. Pouchet, “Polybench: The polyhedral benchmark suite,” URL: https://sourceforge.net/projects/polybench/, 2012. [17] R. T. Mullapudi, A. Adams, D. Sharlet, J. Ragan-Kelley, and K. Fa- tahalian, “Automatically scheduling halide image processing pipelines,” ACM Trans. Graph., vol. 35, no. 4, pp. 83:1–83:11, Jul. 2016. [18] A. Jangda and U. Bondhugula, “An effective fusion and tile size model for optimizing image processing pipelines,” inProceedings of the 23rd ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming, ser. PPoPP ’18. New Y ork, NY , USA: ACM, 2018, pp. 261–275. [19] M. D. Lam, E. E. Rothberg, and M. E. Wolf, “The cache performance and optimizations of blocked algorithms,” inACM SIGARCH Computer Architecture News, vol. 19, no. 2. ACM, 1991, pp. 63–74. [20] R. Schreiber and J. J. Dongarra, “Automatic blocking of nested loops,” 1990. [21] S. Coleman and K. S. McKinley, “Tile size selection using cache organization and data layout,” inACM SIGPLAN Notices, vol. 30, no. 6. ACM, 1995, pp. 279–290. [22] C.-h. Hsu and U. Kremer, “A quantitative analysis of tile size selection algorithms,” The Journal of Supercomputing, vol. 27, no. 3, pp. 279–294, 2004. [23] V . Sarkar and N. Megiddo, “An analytical model for loop tiling and its solution,” in Performance Analysis of Systems and Software, 2000. ISPASS. 2000 IEEE International Symposium on . IEEE, 2000, pp. 146–153. [24] N. Mitchell, K. H ¨ogstedt, L. Carter, and J. Ferrante, “Quantifying the multi-level nature of tiling interactions,” International Journal of Parallel Programming, vol. 26, no. 6, pp. 641–670, 1998. [25] K. Y otov, X. Li, G. Ren, M. Garzaran, D. Padua, K. Pingali, and P . Stodghill, “Is search really necessary to generate high-performance blas?” Proceedings of the IEEE, vol. 93, no. 2, pp. 358–386, 2005. [26] K. Esseghir, “Improving data locality for caches,” Ph.D. dissertation, Rice University, 1993. [27] G. Rivera and C.-W. Tseng, “A comparison of compiler tiling algo- rithms,” in Compiler Construction. Springer, 1999, pp. 1–99. [28] S. Mehta, G. Beeraka, and P .-C. Y ew, “Tile size selection revisited,” ACM Trans. Archit. Code Optim., vol. 10, no. 4, pp. 35:1–35:27, Dec. 2013. [29] R. C. Whaley and J. J. Dongarra, “Automatically tuned linear algebra software,” in Proceedings of the 1998 ACM/IEEE conference on Super- computing. IEEE Computer Society, 1998, pp. 1–27. [30] P . M. Knijnenburg, T. Kisuki, K. Gallivan, and M. F. O’Boyle, “The effect of cache models on iterative compilation for combined tiling and unrolling,” Concurrency and Computation: Practice and Experience , vol. 16, no. 2-3, pp. 247–270, 2004. [31] B. B. Fraguela, M. G. Carmueja, and D. Andrade, “Optimal tile size selection guided by analytical models,”parameters, vol. 10, p. 14, 2005. [32] J. Shirako, K. Sharma, N. Fauzia, L.-N. Pouchet, J. Ramanujam, P . Sadayappan, and V . Sarkar, “Analytical bounds for optimal tile size selection,” in Proceedings of the 21st International Conference on Compiler Construction, ser. CC’12. Berlin, Heidelberg: Springer- V erlag, 2012, pp. 101–121. [33] T. Y uki, L. Renganarayanan, S. Rajopadhye, C. Anderson, A. E. Eichenberger, and K. O’Brien, “Automatic creation of tile size selection models,” in Proceedings of the 8th annual IEEE/ACM international symposium on Code generation and optimization . ACM, 2010, pp. 190–199. [34] C. Mendis, A. Renda, S. Amarasinghe, and M. Carbin, “Ithemal: Accurate, portable and fast basic block throughput estimation using deep neural networks,” 2018. [35] M. Rahman, L.-N. Pouchet, and P . Sadayappan, “Neural network assisted tile size selection,” 2010. [36] D. Cociorva, J. W. Wilkins, C. Lam, G. Baumgartner, J. Ramanujam, and P . Sadayappan, “Loop optimization for a class of memory-constrained computations,” in Proceedings of the 15th International Conference on Supercomputing, ser. ICS ’01. New Y ork, NY , USA: ACM, 2001, pp. 103–113. [37] A. Qasem and K. Kennedy, “Profitable loop fusion and tiling using model-driven empirical search,” in Proceedings of the 20th Annual International Conference on Supercomputing, ser. ICS ’06. New Y ork, NY , USA: ACM, 2006, pp. 249–258. [38] U. Beaugnon, A. Pouille, M. Pouzet, J. Pienaar, and A. Cohen, “Op- timization space pruning without regrets,” in Proceedings of the 26th International Conference on Compiler Construction, ser. CC 2017. New Y ork, NY , USA: ACM, 2017, pp. 34–44. [39] M. Christen, O. Schenk, and H. Burkhart, “Patus: A code generation and autotuning framework for parallel iterative stencil computations on modern microarchitectures,” in 2011 IEEE International Parallel Distributed Processing Symposium, May 2011, pp. 676–687. [40] T. Henretty, R. V eras, F. Franchetti, L.-N. Pouchet, J. Ramanujam, and P . Sadayappan, “A stencil compiler for short-vector simd architectures,” in Proceedings of the 27th International ACM Conference on Interna- tional Conference on Supercomputing, ser. ICS ’13. New Y ork, NY , USA: ACM, 2013, pp. 13–24. [41] T. Henretty, K. Stock, L.-N. Pouchet, F. Franchetti, J. Ramanujam, and P . Sadayappan, “Data layout transformation for stencil computations on short-vector simd architectures,” inProceedings of the 20th International Conference on Compiler Construction: Part of the Joint European Conferences on Theory and Practice of Software, ser. CC’11/ETAPS’11. Berlin, Heidelberg: Springer-V erlag, 2011, pp. 225–245. [42] Y . Tang, R. A. Chowdhury, B. C. Kuszmaul, C.-K. Luk, and C. E. Leis- erson, “The pochoir stencil compiler,” inProceedings of the twenty-third annual ACM symposium on Parallelism in algorithms and architectures. ACM, 2011, pp. 117–128. 380 [43] N. Prajapati, W. Ranasinghe, S. Rajopadhye, R. Andonov, H. Djidjev, and T. Grosser, “Simple, accurate, analytical time modeling and optimal tile size selection for gpgpu stencils,” in Proceedings of the 22Nd ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming, ser. PPoPP ’17. New Y ork, NY , USA: ACM, 2017, pp. 163–177. [44] T. Gysi, C. Osuna, O. Fuhrer, M. Bianco, and T. C. Schulthess, “Stella: A domain-specific tool for structured grid methods in weather and climate models,” in Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis, ser. SC ’15. New Y ork, NY , USA: ACM, 2015, pp. 41:1–41:12. [45] S. W. Liao, S. J. Tsai, C. H. Y ang, and C. K. Lo, “Locality-aware scheduling for stencil code in halide,” in 2016 45th International Conference on Parallel Processing Workshops (ICPPW), Aug 2016, pp. 72–77. 381 National Institutional Ranking Framework Ministry of Education Government of India Welcome to Data Capturing System: ENGINEERING Submitted Institute Data for NIRF'2024' Institute Name: V. S. B. Engineering College [IR-E-C-36944] Sanctioned (Approved) Intake Academic Year 2022-23 2021-22 2020-21 2019-20 2018-19 2017-18 UG [4 Years Program(s)] 1080 1080 1050 1050 - - PG [2 Year Program(s)] 45 45 - - - - Total Actual Student Strength (Program(s) Offered by Your Institution) (All programs of all years) No. of Male Students No. of Female Students Total Students Within State (Including male & female) Outside State (Including male & female) Outside Country (Including male & female) Economically Backward (Including male & female) Socially Challenged (SC+ST+OBC Including male & female) No. of students receiving full tuition fee reimbursement from the State and Central Government No. of students receiving full tuition fee reimbursement from Institution Funds No. of students receiving full tuition fee reimbursement from the Private Bodies No. of students who are not receiving full tuition fee reimbursement UG [4 Years Program(s)] 2267 1254 3521 3514 7 0 1578 1898 1146 771 0 1559 PG [2 Year Program(s)] 5 16 21 21 0 0 9 12 12 0 0 9 Placement & Higher Studies UG [4 Years Program(s)]: Placement & higher studies for previous 3 years Academic Year No. of first year students intake in the year No. of first year students admitted in the year Academic Year No. of students admitted through Lateral entry Academic Year No. of students graduating in minimum stipulated time No. of students placed Median salary of placed graduates(Amount in Rs.) No. of students selected for Higher Studies 2017-18 690 634 2018-19 12 2020-21 558 472 450000(Four Lakh Fifty Thousand) 17 2018-19 870 684 2019-20 14 2021-22 560 487 476000(Four Lakh seventy six Thousand) 16 2019-20 1050 843 2020-21 20 2022-23 766 680 485000(Four Lakhs and eighty five thousand) 5 PG [2 Years Program(s)]: Placement & higher studies for previous 3 years Academic Year No. of first year students intake in the year No. of first year students admitted in the year Academic Year No. of students graduating in minimum stipulated time No. of students placed Median salary of placed graduates(Amount in Rs.) No. of students selected for Higher Studies 2019-20 54 10 2020-21 7 2 300000(Three Lakhs) 0 2020-21 45 5 2021-22 4 1 300000(Three Lakhs) 0 2021-22 45 9 2022-23 4 2 306000( three lakhs sis thousand) 0 Ph.D Student Details Ph.D (Student pursuing doctoral program till 2022-23 Students admitted in the academic year 2023-24 should not be entered here.) Total Students Full Time 0 Part Time 0 No. of Ph.D students graduated (including Integrated Ph.D) 2022-23 2021-22 2020-21 Full Time 0 0 0 Part Time 0 0 1 Financial Resources: Utilised Amount for the Capital expenditure for previous 3 years Academic Year 2022-23 2021-22 2020-21 Utilised Amount Utilised Amount Utilised Amount Annual Capital Expenditure on Academic Activities and Resources (excluding expenditure on buildings) Library ( Books, Journals and e-Resources only) 3807023 (Thirty eight Lakhs Seven Thousand and twenty three ) 2902009 (Twenty Nine Lakhs Two Thousand and Nine) 237715 (Two Lakhs Thirty Seven Thousand Seven Hundred and Fifteen) New Equipment and software for Laboratories 7920927 (Seventy Nine Lakhs Twenty Thousand Nine Hundred Twenty Seven ) 5822398 (Fifty Eight Lakhs Twenty Two Thousand Three Hundred and Ninety Eight) 5797130 (Fifty Seven Lakhs Ninety Seven Thousand One Hundred and Thirty) Engineering Workshops 2401745 (Twenty Four Lakhs One Thousand Seven Hundred Forty Five ) 1450542 (Fourteen Lakhs Fifty Thousand Five Hundred and Forty Two) 1351945 (Thirteen Lakhs Fifty One Thousand Nine Hundred and Forty Five) Other expenditure on creation of Capital Assets (For setting up classrooms, seminar hall, conference hall , library, Lab, Engg workshops excluding expenditure on Land and Building) 22745562 (Two Crore Twenty Seven Lakhs Forty Five Thousand Five Hundred Sixty Two) 2954641 (Twenty Nine Lakhs Fifty Four Thousand Six Hundred and Forty One) 37378481 (Three Crore Seventy Three Lakhs Seventy Eight Thousand Four Hundred and Eighty One) Financial Resources: Utilised Amount for the Operational expenditure for previous 3 years Academic Year 2022-23 2021-22 2020-21 Utilised Amount Utilised Amount Utilised Amount Annual Operational Expenditure Salaries (Teaching and Non Teaching staff) 107478268 (Ten Crore Seventy Four Lakhs Seventy Eight Thousand Two Hundred Sixty Eight) 88842585 (Eight Crore Eighty Eight Lakhs Forty Two Thousand Five Hundred and Eighty Five) 75443418 (Seven Crore Fifty Four Lakhs Forty Three Thousand Four Hundred and Eighteen) Maintenance of Academic Infrastructure or consumables and other running expenditures(excluding maintenance of hostels and allied services,rent of the building, depreciation cost, etc) 27973800 (Two Crore Seventy Nine Lakhs Seventy Three Thousand Eight Hundred) 88922338 (Eight Crore Eighty Nine Lakhs Twenty Two Thousand Three Hundred and Thirty Eight) 53584970 (Five Crore Thirty Five Lakhs Eighty Four Thousand Nine Hundred and Seventy) Seminars/Conferences/Workshops 2244064 (Twenty Two Lakhs Forty Four Thousand Sixty Four) 1009963 (Ten Lakhs Nine Thousand Nine Hundred and Sixty Three) 1445441 (Fourteen Lakhs Forty Five Thousand Four Hundred and Forty One) IPR Calendar year 2022 2021 2020 No. of Patents Published 24 24 9 No. of Patents Granted 10 1 0 Sponsored Research Details Financial Year 2022-23 2021-22 2020-21 Total no. of Sponsored Projects 6 4 6 Total no. of Funding Agencies 2 3 1 Total Amount Received (Amount in Rupees) 198388 420763 3195777 Amount Received in Words One Lakh Ninety Eight Thousand Three Hundred and Eighty Eight Four Lakhs Twenty Thousand Seven Hundred and Sixty Three Thirty One Lakh Ninety Five thousand Seven Hundred and Seventy Seven Only Consultancy Project Details Financial Year 2022-23 2021-22 2020-21 Total no. of Consultancy Projects 4 14 1 Total no. of Client Organizations 2 2 1 Total Amount Received (Amount in Rupees) 193265 436472 300000 Amount Received in Words One Lakh Ninety Three Thousand Two Hundred and Sixty Five Four Lakhs Thirty Six Thousand Four Hundred and Seventy Two Three lakhs only PCS Facilities: Facilities of physically challenged students 1. Do your institution buildings have Lifts/Ramps? Yes, more than 80% of the buildings 2. Do your institution have provision for walking aids, including wheelchairs and transportation from one building to another for handicapped students? Yes 3. Do your institution buildings have specially designed toilets for handicapped students? Yes, more than 80% of the buildings Faculty Details Srno Name Age Designation Gender Qualification Experience (In Months) Currently working with institution? Joining Date Leaving Date Association type 1 DINESH M 33 Assistant Professor Male M.E. 132 Yes 04-06-2019 -- Regular 2 BALAJI V 31 Assistant Professor Male M.E. 123 Yes 14-05-2012 -- Regular 3 SENTHILKUMAR P R 36 Assistant Professor Male M. Phil 157 No 01-08-2012 26-09-2023 Regular 4 MOHAMED NASURUDEEN M 33 Assistant Professor Male M.Tech 132 Yes 16-05-2019 -- Regular 5 Dr UMAMAHESWARI K 41 Professor Female Ph.D 207 Yes 01-12-2017 -- Regular 6 KRISHNAN R 38 Assistant Professor Male M.E. 151 Yes 03-07-2013 -- Regular 7 GUNASEKARAN S 45 Associate Professor Male M.Tech 292 Yes 02-06-2010 -- Regular 8 DHANABAL M 32 Assistant Professor Male M.E. 137 Yes 02-07-2014 -- Regular 9 DR KALYANASUNDAR AM R 49 Assistant Professor Male Ph.D 234 Yes 02-07-2014 -- Regular 10 THANGAVEL M 32 Assistant Professor Male M.E. 131 Yes 02-01-2015 -- Regular 11 PRABAKARAN S 34 Assistant Professor Male M.E. 161 Yes 04-05-2012 -- Regular 12 MOHANAVEL G 32 Assistant Professor Male M.E. 136 Yes 27-04-2018 -- Regular 13 SRI VENKATALAKSHMI R 28 Assistant Professor Female M.E. 92 Yes 06-06-2018 -- Regular 14 KAPIL DEV N 35 Assistant Professor Male M.E. 152 Yes 18-07-2018 -- Regular 15 Dr GANESH BABU P 53 Professor Male Ph.D 235 Yes 20-08-2018 -- Regular 16 RAJAGOPAL R 37 Assistant Professor Male M. Phil 147 Yes 16-07-2018 -- Regular 17 GOWRI SHANKAR R 34 Assistant Professor Male M.E. 151 Yes 03-06-2015 -- Regular 18 ANBUMANI P 34 Assistant Professor Male M.E. 153 Yes 04-01-2016 -- Regular 19 VINOTH KUMAR S 36 Assistant Professor Male M.E. 131 Yes 09-06-2014 -- Regular 20 Dr SUMITHIRADEVI C 42 Associate Professor Female Ph.D 252 Yes 02-01-2009 -- Regular 21 ASHOK KUMAR R 38 Assistant Professor Male M.E. 137 Yes 13-06-2016 -- Regular 22 DR RAJU P 41 Associate Professor Male Ph.D 236 Yes 19-03-2012 -- Regular 23 DHAYABARANI R 51 Associate Professor Female M.E. 305 Yes 09-06-2003 -- Regular 24 Dr PRABAKARAN T R 59 Professor Male Ph.D 201 Yes 30-06-2017 -- Regular 25 DEVARAJ P 31 Assistant Professor Male M.E. 113 Yes 04-06-2016 -- Regular 26 VASUDEVAN M 34 Assistant Professor Male M.E. 127 Yes 07-05-2018 -- Regular 27 PRAGASH S 32 Assistant Professor Male M.E. 132 Yes 29-05-2018 -- Regular 28 Rajkumar K 31 Assistant Professor Male M.E. 92 Yes 01-07-2017 -- Regular 29 NARESHKUMAR P 37 Assistant Professor Male M.E. 190 Yes 01-07-2014 -- Regular 30 POORNIMA P 34 Assistant Professor Female M.E. 163 Yes 01-07-2014 -- Regular 31 MOHANASELVAN C 31 Assistant Professor Male M.E. 122 Yes 01-07-2015 -- Regular 32 KIRUBASHANKAR T S 42 Associate Professor Male M.E. 243 Yes 04-07-2013 -- Regular 33 SIVAKUMAR R 44 Associate Professor Male M.E. 273 Yes 10-04-2006 -- Regular 34 SELVARASU A 40 Assistant Professor Male M.E. 190 Yes 16-07-2012 -- Regular 35 KARTHEESWARAN R 31 Assistant Professor Male M.E. 119 Yes 02-01-2015 -- Regular 36 ARUN B 31 Assistant Professor Male M.E. 114 Yes 08-06-2017 -- Regular 37 ARUL N 32 Assistant Professor Male M.E. 119 Yes 02-06-2015 -- Regular 38 Dr RAGHUPATHY R 35 Associate Professor Male Ph.D 154 Yes 21-02-2011 -- Regular 39 DINESH KUMAR D 31 Assistant Professor Male M.E. 130 Yes 13-08-2018 -- Regular 40 GEETHA S 28 Assistant Professor Female M.E. 92 Yes 09-08-2018 -- Regular 41 NELSON S 36 Assistant Professor Male M.E. 188 Yes 23-04-2018 -- Regular 42 KEERTHANA S 32 Assistant Professor Female M.E. 100 Yes 05-06-2018 -- Regular 43 SWARNALATHA A P 33 Assistant Professor Female M.E. 80 Yes 06-06-2018 -- Regular 44 Dr MAHARAJAN C 31 Assistant Professor Male Ph.D 100 Yes 07-06-2018 -- Regular 45 Dr GOMATHI P S 46 Professor Female Ph.D 275 Yes 24-05-2010 -- Regular 46 MANGALARAJ K 38 Assistant Professor Male M. Phil 163 Yes 09-02-2015 -- Regular 47 BRINDHA G 35 Assistant Professor Female M. Phil 102 Yes 05-10-2017 -- Regular 48 Dr PARTHIBAN M 39 Associate Professor Male Ph.D 102 Yes 24-10-2017 -- Regular 49 KALAICHELVI K 55 Associate Professor Female M.E. 240 Yes 01-06-2009 -- Regular 50 MANIVANNAN K 38 Assistant Professor Male M.Tech 102 Yes 03-10-2017 -- Regular 51 SIVALINGAM T 34 Assistant Professor Male M.E. 125 Yes 01-07-2015 -- Regular 52 Dr NIRMALKANNAN V 41 Dean / Principal / Director / Vice Chancellor Male Ph.D 233 Yes 08-11-2017 -- Regular 53 THARANI B 35 Assistant Professor Female M.E. 104 Yes 16-08-2018 -- Regular 54 VALLI SUSEELA R 36 Assistant Professor Female M.E. 153 Yes 01-06-2018 -- Regular 55 DR RAJASEKARAN E 57 Professor Male Ph.D 236 Yes 01-06-2018 -- Regular 56 JEGAN R R 36 Assistant Professor Male M.E. 161 Yes 15-12-2017 -- Regular 57 ARUNKUMAR R 37 Assistant Professor Male M.E. 178 Yes 11-12-2017 -- Regular 58 REVATHI M 34 Assistant Professor Female M. Phil 132 Yes 17-01-2018 -- Regular 59 ANANDHAKUMAR P 31 Assistant Professor Male M.E. 91 Yes 04-06-2019 -- Regular 60 SUJITHA S 27 Assistant Professor Female M.E. 60 Yes 12-06-2019 -- Regular 61 JAINULAFDEEN A 35 Assistant Professor Male M.E. 175 Yes 10-06-2019 -- Regular 62 Dr SANGEETHA M 43 Professor Female Ph.D 240 Yes 12-06-2019 -- Regular 63 PREMALATHA N 34 Assistant Professor Female M.E. 133 Yes 01-06-2019 -- Regular 64 SATHYANARAYAN AN M 33 Assistant Professor Male M.E. 128 Yes 07-06-2019 -- Regular 65 MOHAN PERIYASAMY M 33 Assistant Professor Male M.E. 97 No 10-06-2019 14-11-2022 Regular 66 Dr SELVAKUMAR J 44 Professor Male Ph.D 235 Yes 07-08-2019 -- Regular 67 VELAVAN R 41 Assistant Professor Male M.E. 143 Yes 06-06-2019 -- Regular 68 SANTHASEELAN 36 Assistant Professor Male M.Tech 146 Yes 06-06-2019 -- Regular 69 JENISH S 49 Assistant Professor Male M.Tech 117 Yes 08-06-2019 -- Regular 70 Dr GNANAPRAGASAM G 41 Associate Professor Male Ph.D 154 Yes 06-12-2019 -- Regular 71 LATHA P 44 Associate Professor Female M.E. 187 Yes 15-07-2019 -- Regular 72 Maalini D 35 Assistant Professor Female M.E. 75 Yes 16-12-2019 -- Regular 73 Ramprakash A 36 Assistant Professor Male M.E. 104 Yes 18-06-2019 -- Regular 74 Karthi K 28 Assistant Professor Male M.E. 67 Yes 24-06-2019 -- Regular 75 Dr Anishkumar M 42 Professor Male Ph.D 225 Yes 22-07-2019 -- Regular 76 Subashini K 29 Assistant Professor Female M.Tech 76 Yes 13-06-2019 -- Regular 77 Suvitha S 28 Assistant Professor Female M. Phil 59 Yes 15-07-2019 -- Regular 78 SHOBANA M 35 Assistant Professor Female M.E. 78 Yes 13-12-2017 -- Regular 79 DR AROCKIA MARRY P 44 Professor Female Ph.D 249 Yes 31-01-2020 -- Regular 80 Dr KARTHI S 42 Associate Professor Male Ph.D 157 Yes 02-11-2020 -- Regular 81 MOHANAPRAKASH K 36 Assistant Professor Male M.E. 179 Yes 04-11-2020 -- Regular 82 PRASANTH B 31 Assistant Professor Male M.E. 96 Yes 17-08-2020 -- Regular 83 Dr SENTHIL KUMAR B 47 Professor Male Ph.D 263 Yes 12-10-2020 -- Regular 84 CAPTAN PRABAKARAN A 32 Assistant Professor Male M.E. 116 Yes 24-08-2020 -- Regular 85 NAVANEETHA KRISHNAN G 36 Assistant Professor Male M.E. 99 Yes 05-11-2020 -- Regular 86 RAJASEKAR K 39 Assistant Professor Male M.E. 121 Yes 06-11-2020 -- Regular 87 MAHESH S 34 Assistant Professor Male Ph.D 144 Yes 03-11-2020 -- Regular 88 MAHALAKSHMI V 26 Assistant Professor Female M. Phil 41 Yes 04-01-2021 -- Regular 89 PRAKASH AYYAPPAN B 44 Assistant Professor Male M.E. 131 No 30-12-2020 30-05-2022 Regular 90 Dr ARULKUMAR P 42 Professor Male Ph.D 235 Yes 29-12-2020 -- Regular 91 NANDHINIDEVI S 42 Assistant Professor Female M.E. 172 Yes 30-12-2020 -- Regular 92 Dr KARTHIGA D 32 Assistant Professor Female Ph.D 41 Yes 19-01-2021 -- Regular 93 Dr POORNACHANDRA N R 30 Assistant Professor Male Ph.D 41 Yes 28-12-2020 -- Regular 94 SAHEBZATHI S 39 Assistant Professor Female M.E. 88 Yes 23-01-2021 -- Regular 95 PRABAKARAN A 32 Assistant Professor Male M.E. 85 Yes 25-01-2021 -- Regular 96 PRAVEENKUMAR G 38 Assistant Professor Male M.E. 152 Yes 25-01-2021 -- Regular 97 PURUSHOTHAMAN S 34 Assistant Professor Male M.E. 132 Yes 29-12-2020 -- Regular 98 LAKSHMI R 33 Assistant Professor Female M.E. 70 Yes 27-01-2021 -- Regular 99 KAMALI R 26 Assistant Professor Female M.E. 41 Yes 27-01-2021 -- Regular 100 ARIVARASAN S 38 Associate Professor Male M.Tech 206 Yes 29-01-2021 -- Regular 101 INDUMATHY S 27 Assistant Professor Female M.Tech 41 Yes 29-01-2021 -- Regular 102 MERLIN FLAVIA E 26 Assistant Professor Female M. Phil 41 Yes 29-01-2021 -- Regular 103 VENKATRAMANA G 30 Assistant Professor Male M.Tech 87 Yes 29-01-2021 -- Regular 104 VIJAYARAGHAVAN T 32 Assistant Professor Male M.E. 99 Yes 30-01-2021 -- Regular 105 MOHAMMED KEERAN V 33 Assistant Professor Male M.E. 116 Yes 30-01-2021 -- Regular 106 VENGAIMARBHAN D 38 Assistant Professor Male M.E. 124 Yes 10-02-2021 -- Regular 107 JANANI S 27 Assistant Professor Female M.E. 40 Yes 10-02-2021 -- Regular 108 JAISHANKAR V 34 Assistant Professor Male M.E. 41 Yes 31-01-2021 -- Regular 109 SARANYADEVI M 31 Assistant Professor Female M.E. 69 Yes 09-02-2021 -- Regular 110 MANOJSAGAR K 33 Assistant Professor Male M.E. 125 Yes 12-03-2021 -- Regular 111 Dr AMIT KUMAR SINGH 45 Associate Professor Male Ph.D 111 Yes 07-04-2021 -- Regular 112 KATHU SARA RENJI 32 Assistant Professor Female M.E. 39 Yes 30-03-2021 -- Regular 113 Dr MURUGESA THANU N 57 Professor Male Ph.D 303 Yes 24-02-2020 -- Regular 114 NANDHINI P 31 Assistant Professor Female M.E. 89 Yes 17-08-2020 -- Regular 115 Dr KATHIR I 54 Professor Male Ph.D 371 Yes 12-08-2021 -- Regular 116 ANANDAN D 38 Assistant Professor Male M.E. 161 Yes 13-08-2021 -- Regular 117 RAJESHKUMAR S 36 Assistant Professor Male M.E. 134 Yes 12-08-2021 -- Regular 118 VINAYAGAMOORT HY A 41 Assistant Professor Male M. Phil 203 Yes 11-08-2021 -- Regular 119 SYED FAZLULLAH S 50 Assistant Professor Male M. Phil 239 Yes 13-08-2021 -- Regular 120 BHAVADHARANI K 25 Assistant Professor Female M.E. 21 Yes 06-07-2022 -- Regular 121 PALRAJ R 53 Assistant Professor Male M.E. 192 Yes 11-05-2022 -- Regular 122 RANJITH G 29 Assistant Professor Male M.E. 45 Yes 14-03-2022 -- Regular 123 SENTHIL KUMAR K 36 Assistant Professor Male M.E. 150 Yes 14-03-2022 -- Regular 124 MOHAN S 52 Assistant Professor Male M.E. 144 Yes 07-03-2022 -- Regular 125 MANIKANDAN T 35 Assistant Professor Male M.E. 42 Yes 04-03-2022 -- Regular 126 ABIRAMI M 31 Assistant Professor Female M.E. 60 Yes 30-11-2021 -- Regular 127 DR ZULAIKHA BEEVI S 52 Assistant Professor Female Ph.D 208 Yes 16-09-2021 -- Regular 128 SRINIVAS B 38 Assistant Professor Male M.Tech 148 Yes 15-07-2022 -- Regular 129 SARANYA R 33 Assistant Professor Female M.E. 84 Yes 15-06-2022 -- Regular 130 FRANKLIN JINO R E 42 Assistant Professor Male M.Tech 168 Yes 15-06-2022 -- Regular 131 ARIVOLI R 38 Assistant Professor Male M.Tech 177 Yes 11-05-2022 -- Regular 132 DR KALAIARASI G 36 Associate Professor Female Ph.D 144 Yes 18-07-2022 -- Regular 133 DR ASHOK J 43 Associate Professor Male Ph.D 187 Yes 15-07-2022 -- Regular 134 DR KAVITHA K 50 Professor Female Ph.D 268 Yes 20-04-2022 -- Regular 135 MAHESHKUMAR K 36 Assistant Professor Male M.Tech 96 Yes 14-03-2022 -- Regular 136 PERIYATHAMBI P 43 Assistant Professor Male M.Tech 194 Yes 07-02-2022 -- Regular 137 DHINESH G 34 Assistant Professor Male M.E. 90 Yes 29-09-2021 -- Regular 138 SHARMELA K 31 Assistant Professor Female M.E. 36 Yes 07-03-2022 -- Regular 139 DR RAMESH BABU R 43 Associate Professor Male Ph.D 216 Yes 15-09-2021 -- Regular 140 VIJAYA BALA N 54 Assistant Professor Female M.E. 195 Yes 26-08-2021 -- Regular 141 SUBRAMANI RAO R 37 Assistant Professor Male M.Tech 120 Yes 18-07-2022 -- Regular 142 DR SARAVANAN G 44 Professor Male Ph.D 219 Yes 24-03-2022 -- Regular 143 RAJESH S 35 Assistant Professor Male M.E. 82 Yes 03-09-2021 -- Regular 144 LAVANYA M 33 Assistant Professor Female M.Tech 50 Yes 01-09-2021 -- Regular 145 KUMARAVEL J 35 Assistant Professor Male M.E. 120 Yes 28-07-2022 -- Regular 146 VAIRAMANI G 34 Assistant Professor Male M.E. 142 Yes 24-01-2022 -- Regular 147 DR THANGADURAI K R 50 Professor Male Ph.D 233 Yes 24-01-2022 -- Regular 148 ASHOK JAIN X S 36 Assistant Professor Male M.E. 117 Yes 21-01-2022 -- Regular 149 DR KANAGARAJU T 41 Assistant Professor Male Ph.D 193 Yes 19-01-2022 -- Regular 150 DR AMRISHRAJ D 33 Assistant Professor Male Ph.D 39 Yes 12-01-2022 -- Regular 151 SARAVANAN G 27 Assistant Professor Male M.Tech 13 Yes 05-01-2022 -- Regular 152 BASKAR BABU 34 Assistant Professor Male M.E. 72 Yes 08-09-2021 -- Regular 153 DR NATESH M 36 Assistant Professor Male Ph.D 129 Yes 30-08-2021 -- Regular 154 PRASATH S 30 Assistant Professor Male M.Tech 48 Yes 08-06-2022 -- Regular 155 SOWMIYA M 26 Assistant Professor Male M.E. 13 Yes 02-03-2022 -- Regular 156 MANGAIYAR THILAGAM P 32 Assistant Professor Female M.E. 81 Yes 25-02-2022 -- Regular 157 JOSEPH VIANNY X 27 Assistant Professor Male M.E. 21 Yes 15-12-2021 -- Regular 158 DHANAYENDRAN R 26 Assistant Professor Male M.E. 24 Yes 14-12-2021 -- Regular 159 PRASANNA KUMAR M 27 Assistant Professor Male M.E. 13 Yes 27-08-2021 -- Regular 160 VINOTH T 33 Assistant Professor Male M. Phil 86 Yes 04-07-2022 -- Regular 161 SARAVANAN A 35 Assistant Professor Male M. Phil 72 Yes 15-07-2022 -- Regular 162 AARDRA C 25 Assistant Professor Female M.A 28 Yes 04-05-2022 -- Regular 163 RAVICHANDIRAN R 33 Assistant Professor Male M. Phil 84 Yes 04-05-2022 -- Regular 164 BALASUBRAMANIA N K 42 Assistant Professor Male M. Phil 200 Yes 06-09-2021 -- Regular 165 SHEELA V 39 Associate Professor Female M. Phil 109 Yes 06-09-2021 -- Regular 166 DR KRISHNARAJ S 65 Professor Male Ph.D 399 Yes 27-10-2022 -- Regular 167 SURESH KUMAR V 38 Assistant Professor Male M. Phil 132 Yes 06-06-2022 -- Regular 168 DR SARAVANA KUMAR R 47 Associate Professor Male Ph.D 226 Yes 08-12-2021 -- Regular 169 DR THULASIDHASAN J 36 Assistant Professor Male Ph.D 72 Yes 04-10-2021 -- Regular 170 DR BHASKAR C 41 Assistant Professor Male Ph.D 180 Yes 06-09-2021 -- Regular 171 DR SYED IBRAHIM P S 52 Assistant Professor Male Ph.D 190 Yes 06-09-2021 -- Regular 172 MEENAL ABIRAMI R 36 Assistant Professor Female Ph.D 55 Yes 20-07-2022 -- Regular 173 MUTHU KUMAR S 26 Assistant Professor Male Ph.D 13 Yes 08-08-2022 -- Regular 174 SATHYARAJU S 35 Assistant Professor Male M. Phil 56 Yes 01-11-2022 -- Regular 175 RAMESH BABAU K D 46 Assistant Professor Male M. Phil 114 Yes 04-05-2022 -- Regular 176 NAGAMANI S 34 Assistant Professor Male M. Phil 51 Yes 20-04-2022 -- Regular 177 VIJAYAKUMAR M 37 Assistant Professor Male M. Phil 143 Yes 20-04-2022 -- Regular 178 DR VINOTH S 30 Assistant Professor Male Ph.D 13 Yes 04-10-2021 -- Regular 179 PRABHAKARAN T 24 Assistant Professor Male M.Sc. 13 Yes 01-10-2021 -- Regular 180 SARAVANAKUMAR R 27 Assistant Professor Male NET 13 Yes 12-10-2022 -- Regular 181 DR CHINNASAMI S 29 Assistant Professor Male Ph.D 52 No 06-06-2022 13-01-2023 Regular 182 SUGANYA M 30 Assistant Professor Male M. Phil 48 Yes 06-12-2021 -- Regular 183 KANNAN S 40 Assistant Professor Male Ph.D 70 Yes 01-12-2021 -- Regular 184 PRIYA K 33 Assistant Professor Female M. Phil 28 Yes 13-10-2021 -- Regular 185 BASKAR B 28 Assistant Professor Male M. Phil 39 Yes 04-10-2021 -- Regular 186 KAVITHA V 40 Assistant Professor Female M.E. 220 Yes 08-03-2022 -- Regular 187 JAYACANTH SURESH G 55 Assistant Professor Male M.Tech 63 Yes 04-03-2022 -- Regular 188 KEERTHIGA K 32 Assistant Professor Female M.Tech 49 Yes 18-07-2022 -- Regular 189 DR SAM EBENEZER R 36 Associate Professor Male M.Tech 99 Yes 04-05-2022 -- Regular 190 SRIDHIVYA M 28 Assistant Professor Male M.Tech 24 Yes 07-03-2022 -- Regular 191 SARAVANA KUMAR A S 42 Assistant Professor Male M.Tech 132 Yes 02-03-2022 -- Regular 192 DR GOBAL SAMY 38 Associate Professor Male Ph.D 74 Yes 03-12-2021 -- Regular 193 DR SARAVANAN S 47 Associate Professor Male Ph.D 204 Yes 04-10-2021 -- Regular 194 BALASUBRAMANI 37 Assistant Professor Male M.Tech 150 Yes 26-12-2022 -- Regular 195 GOMATHI P 41 Assistant Professor Female Ph.D 186 Yes 01-12-2022 -- Regular 196 PRIYA M 35 Assistant Professor Female M.E. 96 Yes 15-09-2022 -- Regular 197 Dr K BARANITHARAN 44 Associate Professor Male Ph.D 196 Yes 24-01-2022 -- Regular 198 Dr SHUKHASHI ADAK 36 Assistant Professor Male Ph.D 77 No 21-02-2022 22-12-2022 Regular 199 DR RAHUL SINGH 34 Assistant Professor Male Ph.D 16 No 30-03-2022 22-12-2022 Regular 200 Sabari K 32 Assistant Professor Male M.E. 94 Yes 19-08-2021 -- Regular 201 P Anitha 35 Assistant Professor Female M. Phil 50 Yes 01-10-2021 -- Regular 202 DR VENKATACHALAM N 44 Associate Professor Male Ph.D 153 Yes 17-10-2022 -- Regular 203 MR KISHORE KUMAR R 27 Assistant Professor Male NET 6 Yes 07-02-2023 -- Regular 204 DR VENKATESH KUMAR N 47 Assistant Professor Male Ph.D 209 Yes 03-05-2023 -- Regular 205 MR GOBINATH P 30 Assistant Professor Male M.Sc. 5 Yes 09-02-2023 -- Regular 206 MR KARTHIKEYAN M 48 Assistant Professor Male M.E. 6 Yes 14-09-2022 -- Regular 207 MR ANBU A 28 Assistant Professor Male M.Tech 34 Yes 27-01-2023 -- Regular 208 DR BITANG KWRUNG TRIPURA 35 Assistant Professor Male Ph.D 11 Yes 03-01-2023 -- Regular 209 DR TRIPTI DE T 35 Assistant Professor Female Ph.D 42 Yes 30-12-2022 -- Regular 210 MRS NITHYA C 34 Assistant Professor Female M.E. 13 Yes 01-09-2021 -- Regular 211 MRS AAYISHA BEGAM A 27 Assistant Professor Female M.E. 7 Yes 03-05-2023 -- Regular 212 DR SURENDAR P 35 Assistant Professor Male Ph.D 111 Yes 17-10-2022 -- Regular 213 MR ELUMALAI V 36 Assistant Professor Male M.E. 157 Yes 07-04-2023 -- Regular 214 DR VIGNESHWARAN S 32 Assistant Professor Male Ph.D 74 Yes 28-12-2022 -- Regular 215 MRS PARVATHI M 47 Assistant Professor Female M.E. 151 Yes 12-10-2022 -- Regular 216 MR KUMARESAN V 29 Assistant Professor Male M.E. 11 Yes 30-12-2022 -- Regular 217 MRS NITHIYA K 34 Assistant Professor Female M.E. 8 Yes 03-04-2023 -- Regular 218 MR VIJAYAKUMAR G 30 Assistant Professor Male M.E. 8 Yes 03-04-2023 -- Regular 219 MS RAAJYA VARDHINI A 36 Assistant Professor Female M.Tech 11 Yes 30-12-2022 -- Regular 220 MS KAVITHA R P 39 Assistant Professor Female M.Sc. 151 Yes 10-02-2023 -- Regular 221 MR NAGARAJ D 42 Assistant Professor Male M. Phil 102 Yes 28-04-2023 -- Regular 222 DR KEERTHANA R 27 Assistant Professor Female M.Sc. 10 Yes 20-02-2023 -- Regular 223 MR BOOMI P 39 Assistant Professor Male M. Phil 187 Yes 01-02-2023 -- Regular 224 MS JEYASHREE G 26 Assistant Professor Female M.Tech 4 Yes 30-08-2022 -- Regular 225 DR VIJAYAPRITHA S 31 Assistant Professor Female M.Sc. 3 Yes 03-04-2023 -- Regular 226 DR MANIKANDAN R 55 Professor Male Ph.D 294 Yes 30-08-2022 -- Regular 227 MRS KAVIYA G 29 Assistant Professor Female M.E. 38 Yes 03-03-2023 -- Regular 228 MR BASKAR D 51 Assistant Professor Male M.Tech 263 Yes 03-03-2023 -- Regular 229 MRS DEEPIKA D 36 Assistant Professor Female M.E. 11 Yes 28-12-2022 -- Regular 230 MR KUMARAN R 44 Associate Professor Male M.E. 233 Yes 06-06-2019 -- Regular 231 MRS JAYAKUMARI DS 42 Assistant Professor Female M.E. 208 Yes 01-04-2023 -- Regular 232 MS SRIDEVI R 24 Assistant Professor Female M.Sc. 10 Yes 08-02-2023 -- Regular 233 MR KARTHIKEYAN J 31 Assistant Professor Male M.E. 13 Yes 30-12-2021 -- Regular 234 MS NITHYA A 34 Assistant Professor Female M.Tech 42 Yes 27-04-2022 -- Regular 235 MRS MENAGA G 33 Assistant Professor Female M.E. 37 Yes 05-03-2022 -- Regular 236 MRS KAVYA PRIYA J 31 Assistant Professor Female M.E. 13 Yes 04-03-2022 -- Regular 237 MR MANI P 32 Assistant Professor Male M.E. 11 Yes 12-04-2022 -- Regular 238 MRS REVATHI R 40 Assistant Professor Female M.E. 113 Yes 01-04-2023 -- Regular 239 MRS AJITHA KALA DS 47 Assistant Professor Female M.Tech 8 Yes 31-03-2023 -- Regular 240 MRS RAJESWARI S 32 Assistant Professor Female M.Tech 20 Yes 04-03-2022 -- Regular 241 MR KALIMUTHAN C 45 Assistant Professor Male M.Tech 108 Yes 01-03-2023 -- Regular 242 MR BHARATHIRAJA M 32 Assistant Professor Male M.E. 26 Yes 01-03-2023 -- Regular 243 MR SUBRAMANI S 34 Assistant Professor Male M.E. 11 Yes 29-12-2022 -- Regular 244 MRS NAGALAKSHMI N 41 Assistant Professor Female M.E. 20 Yes 03-10-2022 -- Regular 245 MR ASHWIN KUMAR KG 30 Assistant Professor Male M.E. 68 Yes 06-07-2017 -- Regular 246 MR ILANGOVAN B 35 Assistant Professor Male M.E. 112 Yes 01-03-2023 -- Regular 247 MR ELAYARAJA MP 36 Assistant Professor Male M. Phil 25 Yes 03-04-2023 -- Regular 248 MRS LAKSHMI B 34 Assistant Professor Female M. Phil 47 Yes 04-05-2023 -- Regular 249 MRS REBECCAL ANGEL M 31 Assistant Professor Female M.E. 8 Yes 31-03-2023 -- Regular 250 MRS GEETHANJALI G 29 Assistant Professor Female NET 30 Yes 22-02-2023 -- Regular 251 MS SATHYA K 32 Assistant Professor Female M. Phil 19 Yes 06-04-2023 -- Regular 252 MRS EYALARASI V 31 Assistant Professor Female M.Tech 10 Yes 01-02-2023 -- Regular 253 MS RENGALAKSHMI P 25 Assistant Professor Female M.Tech 11 Yes 31-08-2022 -- Regular 254 MRS MOHANAPRIYA M 37 Assistant Professor Female MCA 165 Yes 05-05-2014 -- Regular 255 MAHALAKSHMI V 27 Assistant Professor Female M.E. 28 Yes 19-07-2021 -- Regular 256 PRIYADHARSHINI S 27 Assistant Professor Female M.E. 13 Yes 08-12-2021 -- Regular 257 GOWSALYA S 26 Assistant Professor Female M.Tech 19 Yes 30-12-2021 -- Regular 258 GOWRI T 25 Assistant Professor Female M.Tech 19 Yes 30-12-2021 -- Regular This is the post peer-review accepted manuscript of: Amir Hossein Ashouri, Andrea Bignoli, Gianluca Palermo, Cristina Silvano, Sameer Kulkarni, John Cavazos MiCOMP: Mitigating the Compiler Phase-Ordering Problem Using Optimization Sub-Sequences and Machine Learning ACM Transactions on Architecture and Code Optimization, TACO 2015 The published version is available online at: https://doi.org/10.1145/3124452 ©2018 ACM. (Association for Computing Machinery, Inc.). Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for pro/f_it or commercial advantage and that copies bear this notice and the full citation on the /f_irst page. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, or to redistribute to lists, requires prior speci/f_ic permission and/or a fee. Request permissions from Publications Dept., ACM, Inc., fax +1 (212) 869-0481, or permissions@acm.org. " Personal use of this material is permitted. Permission from the editor must be obtained for all other uses, in any current or future media, including reprinting/republishing this material for advertising or promotional purposes, creating new collective works, for resale or redistribution to servers or lists, or reuse of any copyrighted component of this work in other works. brought to you by COREView metadata, citation and similar papers at core.ac.uk provided by Archivio istituzionale della ricerca - Politecnico di Milano 1 MiCOMP: Mitigating the Compiler Phase-ordering Problem using Optimization Sub-sequences and Machine Learning AMIR HOSSEIN ASHOURI, Politecnico di Milano ANDREA BIGNOLI, Politecnico di Milano GIANLUCA PALERMO, Politecnico di Milano CRISTINA SILVANO, Politecnico di Milano SAMEER KULKARNI, University of Delaware JOHN CAVAZOS,University of Delaware Recent compilers offer a vast number of multilayered optimizations, capable of targeting different code segments of an application. Choosing among these optimizations can signi/f_icantly impact the performance of the code being optimized. The selection of the right set of compiler optimizations for a particular code segment is a very hard problem, but /f_inding the best ordering of these optimizations adds further complexity. . The traditional approach of constructing compiler heuristics to solve this problem simply can not cope with the enormous complexity of choosing the right ordering of optimizations for every code segment in an application. The predictive model uses (i) a platform-independent dynamic features, (ii) an encoded version of the compiler sequence and (iii) an exploration heuristic to tackle the problem. Experimental results using the LLVM compiler framework and the Cbench suite show the effectiveness of the clustering and encoding techniques to application-based reordering of passes while using a number of predictive models. We perform statistical analysis on the prediction space and compare against (i) standard optimization levels O2 and O3, (ii) random iterative compilation, and (iii) two recent non-iterative approaches. We demonstrate that our proposed methodology outperforms the performance of -O1, -O2, and -O3 optimiza- tion levels in just a few iterations, reaching an average performance speedup of 1.31 (up to 1.51) on the Cbench benchmark suite. Additional Key Words and Phrases: compilers, machine learning, autotuning, recommender systems ACM Reference format: Amir Hossein Ashouri, Andrea Bignoli, Gianluca Palermo, Cristina Silvano, Sameer Kulkarni, and John cavazos. 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Optimization Sub-sequences and Machine Learning. ACM Transactions on Architecture and Code Optimization , , Article 1 (September 2017), 22 pages. DOI: 10.1145/3124452 1 INTRODUCTION Compiler developers typically design optimization passes in order to transform each code segment of a program to produce an optimized version of an application. The optimizations can be applied at different stages of the compilation process. Optimizing source code by hand is a tedious task and therefore compiler optimizations are provided to automatically transform code. However, these code optimizations are programming language, application, and architecture dependent. Additionally, the word optimization is a misnomer and there is no guarantee the transformed code will perform better than the original version. Understanding the behavior of the optimizations and the actual effect on the source-code and the interaction of the optimizations with each other This work is partially supported by the European Commission Call H2020-FET-HPC program under the grant ANTAREX- 671623. © 2017 Copyright held by the owner/author(s). Publication rights licensed to ACM. This is the author’s version of the work. It is posted here for your personal use. Not for redistribution. The de/f_initive Version of Record was published inACM Transactions on Architecture and Code Optimization , http://dx.doi.org/10.1145/3124452. ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:2 A. H. Ashouri et al. are complex modeling problems. The problem is particularly difficult because compiler developers have to deal with hundreds of different optimizations that can be applied during the different compilation phases and this creates the phase-ordering problem. The phase-ordering problem has been an open-problem in the /f_ield of compiler research for many decades [25, 42]. The inability of researchers to solve the phase-ordering problem has led to advances in the more simple problem of selecting the right set of optimizations, but even this problem has yet to be solved [9, 12]. This process of selecting the right optimizations for each code segment is typically done manually, and the sequence of optimizations is constructed with little insight into the interaction between the preceding compiler optimizations in the sequence. The task of manually constructing heuristics to select the right sequence of compiler optimizations is infeasible given the ever growing number of compiler optimizations being integrated into compiler frameworks. As an example, GCC has more than 200 compiler passes, and LLVM-clang and LLVM-opt each have more than 100 transformations. Additionally, these optimizations are applied at very different phases of the compilation, including analysis passes and loop-nest passes. Most optimization /f_lags are turned off by default, and compiler developers rely on software developers to know which optimizations will bene/f_it their code. Compiler developers provide standard optimization levels, e.g. -O1, -O2, -Os, etc. to introduce a /f_ixed-sequence of compiler optimizations that, on average, bring good performance on a set of benchmarks the compiler developers tested. Finding the best ordering of compiler optimizations can have substantial bene/f_its for performance metrics such as execution time, power consumption, and code-size. To this end, using prede/f_ined optimizations usually is not good enough to bring the best achievable application-speci/f_ic performance. In this paper, we propose a framework in order to mitigate the complexity of the phase-ordering problem. So far, there are two potential techniques we could use to predict good optimization orders for code being optimized: •(i) Intermediate Sequence Prediction : This technique uses a model to predict the current best optimization (from a given set of optimizations) that should be applied based on the characteristics of code in its present state. [5, 24]. •(ii) Complete Sequence Prediction : This technique uses a model to predict the complete se- quence of optimizations that needs to be applied to the code just by looking at characteristics of the code in its original state [10, 34–36]. The framework proposed in this paper, MiCOMP, falls under the second category. It uses pre- dictive models on complete optimization sequences rather than individual optimizations. We characterize applications as a vector of dynamic features that are independent from the target architecture. Predicting the complete optimization sequence to apply to a piece of code, i.e. complete sequence prediction, has the bene/f_it of only requiring a single-round of feature collection of the code before any optimizations are applied to it. In order to use classic machine learning algorithms with the phase-ordering problem, we adapt an encoding scheme to transform variable-length vectors of optimizations into /f_ixed-length vectors. Our prediction models are trained offline and program features and different compiler con/f_igurations are fed as inputs. As outputs, a prediction model produces a speedup number without the need to actually run the code on the target architecture. The dynamic characterization is independent from the architecture the code is running; thus, it can bring portability among different architectures. Additionally, we de/f_ine exploration heuristics to /f_ind the best models in the shortest time. Our metric of time is de/f_ined as the minimum number of predictions from the model to obtain the best version of the code being optimized. The heuristic is based on Adjusted Cosine Similarity [38] to correlate different con/f_igurations of optimizations with their corresponding predicted speedups across all the training data. A recommendation algorithm enables us to explore only a fraction of the con/f_iguration space to reach the best speedups rather than a state-of-the-art sorting/ranking [10, 34–36]. In our experimental results, we show that our technique can outperform LLVM’s highest optimization level of -O3 by just a few predictions (up to 3 in the worst observed case). . We selected the full set of applications from the Ctuning ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:3 Cbench benchmark [14] to assess and evaluate the bene/f_its of the proposed approach and to prove its feasibility. The main contributions of the proposed approach are as follows: •An independent predictive-modeling framework, capable of capturing the correlation between different compiler optimizations and their predicted speedup without having to run optimized code variants on the target platform. Our autotuning framework can be paired with any desired predictive models. •. We have clustered different compiler optimizations, all taken from LLVM’s O3 into 5 different groups. The order of optimizations within a group is internally /f_ixed but the ordering of the groups can be altered. In this work, these groups are called sub-sequences and we exploit the phase-ordering by using these sub-sequences rather than the individual optimizations. By starting from no optimizations (as the baseline) and exploring differ- ent orderings of the sub-sequences using the same optimizations available to -O3, we outperformed -O3. •Adapting a simple mapping technique to encode an optimization sequence into a bit string. The proposed technique transforms a variable-length representation to a /f_ixed-length feature vector representation. It allows us to apply traditional machine learning algorithms since they are mostly designed to cope with /f_ixed-length feature vectors. •Adapting a Recommender System (RS) approach on the prediction space to use dynamic information. The rest of the paper organized as follows: Section 2 presents related work. Section 3 introduces our proposed methodology including all its components. In Section 4, we present our experimental results and evaluate the results by means of several comparisons in the Section 5. We conclude the paper with future work and the conclusion. 2 RELATED WORK Literature on the phase-ordering problem is closely related to the problem of selecting the best set of compiler optimizations in a /f_ixed ordering. Recent literature can be classi/f_ied into two main classes: (i) autotuning and iterative compilation approaches and (ii) applying machine learning to the problem of optimization selection. Autotuning addresses automatic code-generation and optimization by using different scenarios and architectures. It involves building techniques for automatic optimization of different parame- ters in order to maximize or minimize the satisfaction of an objective function. One strategy in autotuning consists of coupling the approach with random generation of code-variants at each run. This technique can generally improve application performance in reference to static-handcrafted compiler optimization sequences [1]. Given the complexity of the iterative compilation problem [9], it has been shown that applying compiler optimization sequences at random can be as good as using other algorithms such as Genetic algorithms or Simulated Annealing to choose which optimizations to apply [1, 10, 12]. Other authors [3, 8] explored compiler Design Space Exploration (DSE) techniques jointly with architectural DSE for VLIW architectures. Applying machine learning to the problem of selecting the best compiler optimizations has been extensively investigated by many researchers in the past. Proposed methodologies [11, 13, 22, 28, 29, 41] were among the /f_irst notable works introducing the use of machine learning to solve compilation problems. Recent related work [4, 6, 7, 34, 35] also tackled the problem of selecting the best compiler optimizations to apply by utilizing Bayesian Networks with an application- independent characterization technique, predictive modeling with dynamic characterization, and predictive modeling with compiler representations (Intermediate Representation (IR)) . There have been different objective functions used with machine learning on the problem: i) A speedup predictor takes as input both the characterization of the program being compiled and an optimization sequence, and it predicts as output the speedup when applying that optimization sequence relative to a default optimization setting. [10, 34, 35] ii) A sequence predictor characterizes a program being ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:4 A. H. Ashouri et al. compiled and uses it as input to a model, and the model predicts a probability distribution of optimizations to apply to that program. [1, 4, 6, 37]. iii) A tournament predictor [36]) takes as input a triple corresponding to the characterization of the program and two optimization sequences. This model predicts whether the speedup after applying the the /f_irst optimization sequence will be more or less than speedup if applying the second optimization sequence. . However, there are a few notable published studies that attempted to solve the problem. Kulkarni and Cavazos [24] have applied Neuro-Evolution for Augmenting Topologies (NEAT) in the Java JikesRVM compiler to phase-ordering by using intermediate sequence prediction. They built prediction models that use as input features of the current state of the transformed source- code and de/f_ine certain stop-condition rules to complete the /f_inal predicted sequence at each iteration. They used source-code features and the Java JikesRVM JIT compiler to experimentally evaluate their approach. In contrast, we tackle the problem using predictive modeling and dynamic independent-characterization of the applications and our proposed methodology enables us to predict the full-sequence in one-shot. Matrins et al. [27] tackled the problem of phase-ordering by a DSE approach that uses a clustering- based selection method for grouping functions with similarities and exploration of a reduced search space resulting from the combination of optimizations previously suggested for the functions in each group. Authors used DNA encoding where program elements (e.g., operators and loops in function granularity) are encoded in a sequence of symbols, and followed by calculating the distance matrix and a tree construction of the optimization set. Consequently, they applied the compiler optimization passes already included in the DSE to measure the reduction in the total exploration time of the search space such as Genetic algorithm. Our proposed approach on the other hand is mainly different, as we mitigate the phase-ordering problem by inducing a prediction model rather than a design space exploration scheme. Once our model is trained, it can be further used for any number of applications under analysis to induce a prediction inexpensively and we believe it will bring scalability in autotuning compilers. Other related work has approached the problem by exhaustively exploring the optimization ordering space at the granularity of functions [ 23]. The exhaustive enumeration these authors proposed, constructs probabilities of enabling/disabling interactions between different optimization sequences, but these probabilities are not speci/f_ic to any program. Jantz et al. [19] proposed two pruning techniques to downsample the optimization space. As a result the authors could employ faster exhaustive phase-ordering searches on the new space. Ashouri et al. introduced an approach that uses predictive modeling to construct an intermediate sequence of optimizations for code being compiled [5]. Other related work used iterative Design Space Exploration (DSE) and clustering- based approaches to down-sample and cluster the available optimizations targeting performance gain and power reduction [30–32]. Our approach, MiCOMP, is signi/f_icantly different compared with those mentioned in the literature. Our work mostly resembles the approach of Park et al. [35, 36]. However, our techniques tackle the signi/f_icantly harder problem of the phase-ordering. We introduce a mapping function that encodes an optimization sequence into a bit string. It preserves the ordering and the repetition of the optimizations. At the same time, the proposed work is able to predict the complete optimization sequence to apply to the unoptimized code, rather than predicting the best optimization to apply to the current state of the optimized code [5, 24]. . We use dynamic architecture independent features to feed into our model. Moreover, we used clustering over all passes in LLVM’s-O3, that tended to perform well, to signi/f_icantly outperform the single optimization sequence performed by-O3 itself. We do that by re-ordering these sub-sequences automatically based on the type of the application under optimization. To summarize, the presented work is the /f_irst approach that uses machine- learning based techniques on the phase-ordering problem to predict the complete sequence of optimizations. In Section 4, we improve the machine-learning model through Recommender System ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:5 techniques and assess the experimental results we obtain against the state-of-the-art phase-ordering approaches. 3 THE PROPOSED METHODOLOGY Compilers typically ship with standard optimization levels (e.g. -O2, -O3 and -Ofast) each tuned during compiler development to obtain a certain level of performance on a standard set of benchmarks. These optimization levels do not always translate to good performance on other applications. The main objective of the proposed methodology is to introduce a compiler autotuning framework, which is able to dynamically reorder the compiler passes within LLVM’s optimization level -O3 , to achieve the maximum speedup for the applications being optimized. We found that if we could reorder sub-sequences of optimizations that tended to perform well, we could signi/f_icantly outperform the single optimization sequence performed by-O3. This process should be customized based on the features of the application under analysis. To mitigate the phase-ordering problem, a model has to be constructed in such a way that it can correlate the effect of using different compiler sequences and the corresponding achievable speedup. MiCOMP uses such a model, and it can (i) recommend good sequences of optimizations that maximize an application’s performance (ii) with very few predictions. Phase-ordering is also complicated by allowing the possibility of variable-length compiler se- quences. State-of-the-art approaches for selecting the right set of optimizations used /f_ixed length feature-vectors [6, 10, 35, 36] to induce a prediction model. During the prediction phase, MiCOMP proposes an iterative process in which different solutions are explored by evaluating different optimization sequences with the potential of leading to higher speedups. We predict optimization sequences that will perform well against using state-of-the-art ranking [35, 36] techniques. Figure 1 illustrates the two main phases of MiCOMP: (i) offline training and (ii) online prediction . The offline training phase is used to learn about the effects of compiler optimizations when compiling an application. In particular, this phase is used to induce a prediction model considering application features and applied optimizations (including order and repetitions). This phase is performed once for each compiler and the model is built on a set of representative applications. In this phase, each application is passed through a single round of feature collection to extract an application’s characteristics. A dynamic pro/f_iler is used to generate a representation of the program in terms of its features. Since a very large set of features is extracted for each application, we apply a dimension-reduction technique to reduce the number of features that is fed as input to the prediction model (e.g. PCA âĂŞ Principal Component Analysis [ 21]). This speeds up the learning during the model construction process. Application-pro/f_iling and dimension-reduction techniques are extensively described in Section 3.1. Next, an application is compiled with different con/f_igurations of compiler optimizations, executed and pro/f_iled in terms of speedup with respect to LLVM ’s-O3. The speedup values together with the reduced program features and an encoded version of the used compiler optimizations (characterized by a /f_ixed-length binary output, see Section 3.3) are fed to a machine learning algorithm to induce the speedup predictor (see Section 3.4). This model can then used during the online phase. The online prediction phase , is used every time a new application is optimized. We use the same feature extraction and dimension reduction techniques described in the offline training phase. The collected features are used to query the speedup prediction model to predict the best set of compiler sequences to apply to an application. The goal of our method is to discover the fewest number of predictions that will be needed to obtain the optimization sequence that gives the best speedup possible. Thus, MiCOMP has been coupled with a heuristic derived from the /f_ield of Recommender Systems (see Section 3.5). This technique is used to obtain a predicted set of optimization sequences where each sequence is as diverse as possible to the other sequences in the set, thus guaranteeing coverage of a large part of the optimization con/f_iguration space, consequently obtaining a set of optimization sequences that are robust to model inaccuracies. ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:6 A. H. Ashouri et al. Applica'on Characteriza 'on Applica'on Characteriza'on Feature Vector Compiler Op'miza'on sub-sequences Phase-ordering Design Space Explora'on LLVM Backend Training applica'on set Mapper Trained Speedup Model Predic've Modeling Speedup w.r.t –O3 Applica'on Characteriza'on Dimension Reduc'on Feature Vector Best Compiler Sequences Target Applica'on ¤ Trained Speedup Model II) Predic'on Phase (online) I) Training Phase (offline) Dimension Reduc'on Recommender System Predicted Speedup Fig. 1. Proposed framework. (i) offline-training phase which is done once and (ii) online-prediction phase for optimizing new unseen applications 3.1 Application Characterization In this work, we used a PIN-based [26] dynamic instrumentation framework to analyze and charac- terize the behavior of applications at execution-time. In particular, our framework provides a high level Micro-architectural Independent Characterization of Applications (MICA) [17] suitable for characterizing applications in a target architecture agnostic manner. There is no static syntactic analysis, but the framework is solely based on dynamic MICA pro/f_iling. The MICA framework reports information about instruction types, memory and register access pattern, potential in- struction level parallelism and a dynamic control /f_low analysis in terms of branch predictability. Overall, the MICA framework characterizes an application in reference to 99 different metrics (or features). Many of these 99 features are strongly correlated (e.g. the number of memory reads with stride smaller than 1K is bounded by the number of reads with stride smaller than 2K). To signi/f_icantly improve the speed of model construction, we applied a dimension reduction by using Principal Component Analysis (PCA) [21] to reduce the number of features used to characterize an application. PCA is a technique to transform a set of correlated features into a set of orthogonal, i.e., uncorrelated principal components. The PCA transformation sorts the principal components by descending order based on their variance [20]. For instance, the /f_irst principal component includes the most input data variability, i.e., this component represents most of the information contained in the input data. To reduce the number of input features, while keeping most of the information contained in the input data, one simply needs to use the /f_irstk principal components as suggested in previous work [17]. In particular, we set k = 5, which captures more than 98% of the overall variance across all training data. . 3.2 Constructing Compiler Sub-sequences In this section, we brie/f_ly explain our novel idea behind clustering certain compiler optimizations as sub-sequences. A phase-ordering optimization sequence represented by the vectoro belongs to the n dimensional factorial space|Ωphases |= n!, wheren represents the number of compiler optimizations under study. However, the mentioned bound is for a simpli/f_ied phase-ordering problem having a /f_ixed length optimization sequence length and no repetitive application of optimizations. Allowing optimizations to be repeatedly applied and a variable length sequence of optimizations will expand the problem space to: |Ωphases _repetition |= mÕ i=0 ni (1) Where n is the number of optimizations under study and m is the maximum desired length for the optimization sequence. Even for reasonable values for n and m, the entire search space is enormous. For example, assumingn and m are both equal to 10, this leads to an optimization search ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:7 aa adce alignment-from-assumptions argpromotion assumption-cache-tracker barrier basicaa basiccg bdce block-freq branch-prob constmerge correlated-propagation deadargelim demanded-bits domtree dse early-cse elim-avail-extern float2int forceattrs functionattrs globaldce globalopt globals-aa gvn indvars inferattrs inline instcombine ipsccp jump-threading lazy-value-info lcssa licm loop-accesses loop-deletion loop-idiom loop-rotate loop-simplify loop-unroll loop-unswitch loop-vectorize loops mem2reg memcpyopt memdep mldst-motion prune-eh reassociate rpo-functionattrs scalar-evolution sccp scoped-noalias simplifycfg slp-vectorizer sroa strip-dead-prototypes tailcallelim targetlibinfo tbaa tti verify Fig. 2. Generated directed graph for LLVM’s -O3. Each node in the graph represents an optimization pass. The edge thickness depicts the strengths in the connection between two nodes. space of more than 11 billion different optimization sequences to select from for each piece of code being optimized [5] 1. 3.2.1 The Optimization Dependence Graph.Mitigating the phase-ordering problem with previous approaches is not practical due to the large number of different possible optimization sequences to select for each piece of code being optimized. MiCOMP proposes to group optimizations into clusters of sub-sequences that are known to perform well, . There are 157 compiler passes in LLVM optimization level -O3 (more than 60 unique compiler passes) and selecting the most promising sub- sequences from these optimizations can positively affect the autotuning process. Among all these 157 compiler passes, some are analysis passes (i.e. basicaa, memdep, etc) which do not transform the code directly, but instead provide analysis information to other compiler passes that follow them. The rest are transformation passes, i.e., Aggressive Dead Code Elimination (adce), Loop Invariant Code Motion (licm), loop-rotate, etc., which perform optimizations on the code 2. In this paper, we introduce the idea of clustering sub-sequences of all the passes available to the optimization level -O3 and adapt prediction models to order these sub-sequences in ways that improve the performance of a particular application. We show that this technique can improve the performance of an application over using -O3 by evaluating a few predicted orderings of the sub-sequences of optimizations. This graph can be represented by a Weighted Adjacency Matrix that has the size of N×N. This matrix can be used for clustering optimizations into different sub-sequences. Figure 2 shows the constructed graph on -O3. 3.2.2 Graph and Sub-sequence Clustering.For our clustering of optimizations into sub-sequences, we could have used any number of the numerous clustering methods proposed in the literature related to Pattern Recognition (e.g. iterative, hierarchical, divisive, etc,) [39]. We selected agglom- erative clustering [43] which is an iterative clustering technique that merges smaller clusters and improves the complexity of k-mean clustering on graphs [39]. A key insight of this method is that 1The problem of phase-ordering does not have deterministic upper-bound in the case of unbounded length. 2http://llvm.org/docs/Passes.html ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:8 A. H. Ashouri et al. it treats clusters as a dynamical system and its samples as states. The algorithm works as follows: Agglomerative clustering, receives as input the matrix of the graph G and the number of desired clusters (nT ) and builds (i) the graph G with k-nearest-neighbors upon computing its Weighted Adjacency Matrix (W ). (ii) The algorithm then calculates the transition probabilities and (iii) forms sample clusters C = {c1, ...,cnc }. (iv) It enters a loop to iteratively try to add more sub-clusters to the already available clusters in C as long as the conditional sum of the all-path integrals within the new sub-clusters maximizes some objective function (argmax) [43]. A path integral is a metric to measure the stability of a dynamical system and is computed by summing the paths within the cluster on the directed graph weighted by transition probabilities. We used the algorithm and tentatively increased the number of max desired clusters until no clusters could be added. The /f_inal /f_ive clusters, namely, the best optimization sub-sequences the algorithm could /f_ind are reported in Section 4 Table 4. 3.2.3 Benefits of Sub-sequences. Clustering optimizations into sub-sequences makes sense. Certain analysis algorithms typically should be done before an optimization in order for the optimization to have any signi/f_icant impact. For example, we may want to run analysis that performs basic block counts and predicts branch instruction outcomes before applying an optimization that reorders the code blocks in an application. Additionally, it is likely that -O3 will contain optimizations that should follow other optimizations in order to obtain the best performance. Thus, forming a cluster of optimizations that should be applied together makes a lot of sense. 3.3 The Proposed Encoder Constructing prediction models for the problem of selecting the right compiler optimizations with /f_ixed-length feature vectors has been extensively studied [10, 34–36]. However, prediction models fall short when correlating program characterizations with the right compiler optimizations to apply when it comes to a variable optimization sequence length [2]. Therefore, we adapt a simple mapping technique to encode an optimization sequence into a bit string. The proposed technique transforms a variable-length representation to a /f_ixed-length feature vector representation. Let A= {α1, . . . ,αN }be the set of all variables, which can be thought of as an alphabet. Every αi is a letter. A /f_inite string of not necessarily distinct letters is called aword. Thus, each word is a concatenation of the form αi1 αi2 ··· αik , where i1, i2, . . . ,ik ∈{1, . . . ,M}. The integer k is the length of the word. We will also allow the empty word which by de/f_inition has length zero. There is a simple way of encoding the space Wof all words of length at most M using the space described by {0, 1}N ×M consisting of all binary strings of the /f_ixed lengthN ×M. To see this, consider the mapping function f : A→{ 0, 1}N which encodes each letter αi to the binary string f (αi )= b1 ···bM , where bj = { 1 if j = i 0 if j , i. Now we de/f_ine the mapping functionF : W→{ 0, 1}N ×M by encoding each wordαi1 αi2 ··· αik to the binary string F(αi1 αi2 ··· αik )= f (αi1 )f (αi2 )··· f (αik ) 0 ··· 0 N −k times , where 0 = 0 ··· 0 is the zero string of length N . Evidently the map F is one-to-one. The image F(W)is much smaller than the target space {0, 1}N ×M , as these sets have ÍM k=0 Nk and 2N ×M elements, respectively. If we identify each element of{0, 1}N ×M with a concatenations1 ···sN of N elements of {0, 1}N , the image F(W)can be simply characterized by the following two requirements: 1. Each si has at most one non-zero binary digit. 2. If si = 0 and sj , 0, then i > j. Given the proposed encoding, there exists a one-to-one (1:1) mapping, F, for every instance of A = {α1, . . . ,αN }with the binary size of N ×M that has the same characteristics of the original presentation ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:9 ADDEBC Α B 10000 00010 00010 00001 01000 00100 Fig. 3. An example of the proposed encoding scheme on the example where we have repetitions and {N = 5, M = 6}: Each le/t_ter represents a compiler sub-sequences containing different compiler optimizations. with the bene/f_it of having a /f_ixedN ×M length. An example of the proposed encoding scheme is shown on the Figure 3. Our adapted mapping function uses a one-hot encoding approach [33] for N=5 and M=6 to assign a single high (1) for each subsequences while other bits are turned off (0). This technique can inexpensively preserve the order and the repetitions of optimizations in a sequence, at the same time it assures the transformed feature vector has /f_ixed-length size. 3.4 Predictive Modeling To this end, the proposed methodology in Figure 1 illustrates the use of predictive modeling in both the offline (training) and online (testing) phases of the process. We used the predictive modeling in the offline training phase to (i) construct the model and in (ii) the online prediction phase we exploit the constructed model on the target application to predict the speedup of a complete optimization sequence without the need to actually apply the sequence of optimizations to the code. 3.4.1 Constructing the Prediction Model. Predictive modeling is the process of constructing, testing, and validating a model to predict an unobserved outcome based on characterization of a state from which to predict the outcome. In this paper, the state being characterized is the code being optimized, and the predicted outcome corresponds to the speedup metric calculated by normalizing the execution time of the current optimization sequence by the execution time of the baseline optimization sequence. The general formulation of the optimization problem is to construct a function that takes as input the features of the unoptimized program being compiled. In other words, this model takes as an input a tuple (F,T )where F is the feature vector of the collected instrumentation of the program being optimized; and T is one of the several possible compiler optimization sequences predicted to perform well on this program. Its output is a prediction of the speedup T should achieve when applied to the original code. 3.4.2 Analysis of Selecting the Compilation Baseline.As explained in Section 3.2, we do not use any of the default compilation optimization levels as a baseline to start from since we used all compiler optimizations passes that are used in -O3 for our clustering purposes (see Section 3.2.2). Additionally, we found that using a baseline compiler optimization level to start from ultimately reduces the speedup achievable from the sequence we construct with predictive modeling. Results suggests that using the MiCOMP optimization sequence without an optimization level as a baseline can lead to substantial bene/f_its compared with using any of-OX optimization levels as a baseline. . Note that using a baseline of -O1, -O2, or -O3 each converge to a sub-optimal speedup. Thus, applying certain sequences causes a degradation in performance as can be seen by using these standard optimization levels as a baseline. The better option is to not use a baseline sequence at all and to allow MICOMP to predict the best sequence to apply on its own. The insights of this experiment are threefold: (i) The clustering technique is bene/f_icial; /f_irst, to gain better speedup values and second, . (ii) The sub-sequences can be coupled with machine-learning techniques so they can be reordered based on the applications being optimized while outperforming the highest standard optimizations levels. (iii) Phase-ordering does matter in the /f_ield of compilers; i.e., using the same set of optimization /f_lags available to-O3, MiCOMP can signi/f_icantly outperform-O3 itself. 3.4.3 Application-specific Prediction. Our machine-learning constructed models can be used for unseen target applications to predict the speedup when applying compiler sequences to them. The predicted speedup values correspond to the optimization sequence applied to the program. For a given input program, /f_irst a feature vector containing dynamic instrumentation is collected. Then our prediction model is fed the features of the program being compiled to predict the expected speedup if an optimization sequence T was applied to ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:10 A. H. Ashouri et al. 0 500 1000 1500 2000 2500 3000 3500 4000 Applied optimization sequences sorted by increasing actual speedup 0.5 0.6 0.7 0.8 0.9 1 1.1 1.2 1.3Normalized speedup to -O3 MiCOMP Proposed Sub-seq Only Baseline -O1 + MiCOMP Proposed Sub-seq Baseline -O2 + MiCOMP Proposed Sub-seq Baseline -O3 + MiCOMP Proposed Sub-seq Region of interest Fig. 4. Empirical analysis of having different compilation baseline across all CBench applications (Harmonic mean). Region of interest is depicted where MiCOMP sub-sequences outperformed other compiler sequences having a fixed standard compilation baseline. it. By predicting the performance of each possible optimization sequence that can be applied, it is possible to rank the optimization sequences according to their expected speedup and only select the sequences to actually apply that are predicted to give the highest speedups. A state-of-the-art ranking approach [34, 36] was used to rank optimization sequences in descending order, and we only select the top N optimization sequences to evaluate their actual optimization quality. In this work, we propose an iterative process in which different solutions are explored to /f_ind those leading to higher speedups. In other words, our proposed exploration technique uses the output of our prediction model to generate an initial exploration strategy, and the exploration strategy dynamically updates itself in order to reach the highest speedup values in the least number of predictions. 3.5 Recommender System Heuristic In the initial steps taken by [5, 24], the authors de/f_ined iterative exploration heuristics, based on the current optimized state of the target application being compiled, to select the next best optimization to apply, which will bring the eventual best speedup. As the current state of the optimized application depends on the optimizations that were already applied, this previous approach required several rounds of feature collection. In this paper, we propose a predictive approach that generates the complete optimization sequence for a program that has not been optimized, thus it needs to collect features only once before any optimizations are applied. 3.5.1 Adjusted Cosine Similarity. Many of the aforementioned state-of-the-art approaches, tackling both the selection and the phase-ordering problem, de/f_ine exploration strategies on the optimizations design space. Yet, to the best of the authors’ knowledge, none of them make use of information in order to dynamically improve the strategy itself. Dynamic information, in our particular case, is the predicted speedup on the sequences already explored and evaluated. The knowledge can be effectively used to improve the initial exploration. The technique we propose, leverages the similarity between the unexplored and the explored optimization sequences. In particular, our proposed technique prioritizes the evaluation of solutions less similar to the ones already explored. This is especially important for the phase-ordering problem where there are a plethora of optimization sequences that need to be explored. The similarity measure is based on how close the achieved speedup is for predicted solutions across all the training data. As an example, let Sp, i and Sp, j be the predicted speedups of the sequences i and j when applied to program p in the set of programs P. We de/f_ine an iterative process to look for predicted similarities ini and j when they were applied to different programs in P. In recommender system (RS), an algorithm called Basic Cosine Similarity is used to correlate users and items. However, computing the similarity using this algorithm has one important drawback: the difference in rating scale are not taken into account. The Adjusted Cosine Similarity offsets this drawback by subtracting ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:11 the corresponding user-average from each co-rated pair and is shown to have the lowest error-rate amongst the different similarity measurement techniques [ 38]. . Using this method, we can compute the Adjusted Cosine Similarity between optimization sequence i and j as: sim (i, j)= Í p∈P (Sp, i − ¯Sp )(Sp, j − ¯Sp ) √Í p∈P (Sp, i − ¯Sp )2 √Í p∈P (Sp, j − ¯Sp )2 (2) where Sp, i is the speedup achieved by sequence i when applied to program p of all set of programs P, and ¯Sp is the average speedup on program p. We use the computed measure to evaluate the correlation between a pair of optimization sequences to bias our exploration strategy. We de/f_ine the exploration strategy inspired by ACS as follows: (1) Sort predicted speedup solutions in decreasing order in a list. (2) Test solutions in order. If the solution to test is too similar to one already tested in the current list iteration, skip it. (3) If the end of the list has been reached and there are still optimization sequences to test, go to 2. Start from the head of the list and exclude already tested solutions. High values of ACS for a pair of optimization sequences are the consequence of achieving pairwise similar speedups across all training data. We employ this measure to hint exploration priority to the solutions that are less similar to the ones already tested. . 4 EXPERIMENTAL RESULTS In this section we evaluate our proposed methodology on an Intel Xeon architecture. We adapted our in- strumentation and architecture-independent tool (Section 3.1) to extract characteristics from a large set of benchmarks from the Ctuning CBench suite [14]. We have used LLVM compilation framework v3.8 (Clang for the frontend/backend and Opt for the optimization passes). The training set consists of different applications ranging from automotive, security, office, and telecom. The list of applications we evaluated is reported in Table 3. Table 4 illustrates the list of different compiler optimizations that are clustered into 5 different sub-sequences (refer to Section 3.2.2) that are derived from LLVM’s-O3. We used the sub-sequences with no baseline in MiCOMP and generate the design space enabling orderings and repetitions of these sub-sequences. The optimizations are /f_ixed within a sub-sequence, but sub-sequences are allowed to appear in any order in the full optimization sequence. The application execution time has been estimated by using the Linux Perf tool. . The execution time is done by averaging three loop-wraps of the speci/f_ic compiled binary with 1s of sleep in between three different executions of those loop-wraps. Therefore, in total, each individual transformed application binary has been executed 9 times as three packages of three loop-wraps to ensure better accuracy of estimations and fairness among the generation of executions. This technique is used both in the training and inference phases. In order to implement a dimension reduction technique we applied PCA. This analysis reveals that by using a 5-D vector of features (a single-dimensional vector of length 5) we can capture 98% of the variance available in the training set. The Principal Components (PCs) have been computed using the MICA features collected from application executions (it is required only once), normalized by standard deviation across all data sets. The proposed methodology is prediction model independent, and we report the results using three different models described in Table 5. To this end, we used (i) a Linear Regression (LR) classi/f_ier using the M5 attribute selection method with default ridge parameter, (ii) a Multilayer Perceptron using the default con/f_iguration, and the (iii) K* algorithm using default settings. In this work, the WEKA machine learning tool [15] has been integrated in our framework. We trained different speedup predictors, each one by excluding from the training application set, one of the applications. This technique is called Leave-One-Out-Cross Validation (LOOCV) and ensures a fair evaluation of our trained models. Validation data is used on the application excluded from the training set for prediction purpose. 4.1 Analysis of the variability of the distributions 4.2 Analysis of the MiCOMP’s training data dependency 4.3 Analysis of the MiCOMP’s timing breakdown An application characterization phase takes between 15 to 40 seconds depending on the type of the application. We noticed a small factor of slowdown when we perform the feature collection phase versus measuring the pure application’s execution time. The overhead is negligible /f_irst, as it is required once and second, the ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:12 A. H. Ashouri et al. Table 1. Analysis of paucity of data when different categories are used Scenario Speedup w.r.t. MiCOMP’s defaultTraining Testing Automotive Security 0.9443 Automotive Telcom 0.9743 Automotive Consumer 0.9432 Automotive Network 0.9896 Automotive Office 0.9896 Table 2. MiCOMP timing breakdown for offline training and online inference Phase Category Time Offline Training (A) Offline Data-collection (32 App) 5 days (B) Model Construction (MLP) 120 sec Online Prediction (C) Susan-c Feature Collection 17.4 sec (D) Susan-c Compilation 4.5 sec (E) Susan-c Execution 9.7 sec (F) Prediction (MLP) 2 sec (G) Recommendation (ACS) 12 sec 0 10 102 103 104 105 Applied optimization sequences sorted by increasing actual speedup 0.7 0.8 0.9 1 1.1 1.2 1.3 1.4 1.5 Normalized speedup to -O3 Max Seq Length 7 (Total: 97 K) Max Seq Length 6 (Total: 19 K) Max Seq Length 5 (Total= 4K) Max Seq Length 4 (Total= 0.781 K) Max Seq Length 3 (Total= 0.156 K) 1.34 1.38 1.44 1.45 1.23 Fig. 5. Empirical analysis of having different compiler sequence lengths on 5 candidate applications: telecom_adpcm_d, jpeg_d, bzipd, network_dijkstra, automotive_bitcount. Note that X axis is in logarithmic scale. speedup gained by using MiCOMP is far higher. In MiCOMP, cross validation is done in a few minutes for each application under analysis. Model construction is heavily correlated with the type of machine learning algorithm we use. We observed LR to be the fastest and MLP to be slowest for our data. 4.4 Analysis of Longer Sequence Length As described in Section 3, MiCOMP requires having upper bound on the sequence length for using the encoding scheme. To this end, we evaluate MiCOMP by having different maximum values for the sequence length. A speedup prediction model requires a one time expensive training be done in order to construct an accurate model. We believe that the longer the sequence length, the better the chance of /f_inding higher speedup values. We have tested our proposed sub-sequences with different maximum sequence lengths to empirically /f_ind the most effective length across all the training applications. This is done also with the goal of scalability and ultimately speeding up the training phase. ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:13 Table 3. Full Cbench Applications under analysis (CTuning CBench suite v1.1 [14]) No. cBench list Description 1 automotive_bitcount Bit counter 2 automotive_qsort1 Quick sort 3 automotive_susan_c Smallest Univalue Segment Assimilating Nucleus Corners 4 automotive_susan_e Smallest Univalue Segment Assimilating Nucleus Edges 5 automotive_susan_s Smallest Univalue Segment Assimilating Nucleus Smoothing 6 security_blow/f_ish_d Symmetric-key block cipher Decoder 7 security_blow/f_ish_e Symmetric-key block cipher Encoder 8 security_rijndael_d AES algorithm Rijndael Decoder 9 security_rijndael_e AES algorithm Rijndael Encoder 10 security_sha NIST Secure Hash Algorithm 11 security_pgp_d public key cryptography for the masses 12 security_pgp_e public key cryptography for the masses 13 telecom_adpcm_c Intel/dvi adpcm coder/decoder Coder 14 telecom_adpcm_d Intel/dvi adpcm coder/decoder Decoder 15 telecom_gsm gsm encoder/decoder 16 telecom_CRC32 32 BIT ANSI X3.66 CRC checksum /f_iles 17 consumer_jpeg_c JPEG kernel 18 consumer_jpeg_d JPEG kernel 19 consumer_lame MP3 encoding engine 20 consumer_mad MPEG audio decoder 21 consumer_tiff2bw convert a color TIFF image to grey scale 22 consumer_tiff2rgba convert a TIFF image to RGBA color space 23 consumer_tiffdither convert a TIFF image to dither noisespace 24 consumer_tiffmedian convert a color TIFF image to create a TIFF palette /f_ile 25 network_dijkstra Dijkstra’s algorithm 26 network_patricia Patricia Trie data structure 27 office_stringsearch1 Boyer-Moore-Horspool pattern match 28 office_ghostscript Aladdin Ghostscript 29 office_ispell An interactive spelling corrector 30 office_rsynth Klatt synthesizer 31 bzip2d BurrowsâĂŞWheeler compression algorithm 32 bzip2e BurrowsâĂŞWheeler compression algorithm Table 4. Candidate clusters of compiler optimizations into sub-sequences (all derived from LLVM -O3) sub- seq Compiler Passes A -alignment-from-assumptions -argpromotion -barrier -bdce -block-freq -branch-prob -constmerge -deadargelim -demanded- bits -dse /f_loat2int -forceattrs -functionattrs -globaldce -globalopt -globals-aa -gvn -indvars -inferattrs -inline -ipsccp -jump- threading -lcssa -loop-accesses -loop-deletion -loop-idiom -loop-unroll -loop-unswitch -loop-vectorize -mldst-motion -prune- eh -reassociate -rpo-functionattrs -sccp -simplyfycfg -sroa -strip-dead-prototypes B -licm -mem2reg C -instcombine -loop-rotate -loop-simplyfy D -memcpyopt E -adce -loop-unswitch -slp-vectorize -tailcallelim Figure 5 gives the Harmonic mean (as suggested by [16] 3) values of the actual speedups using /f_ive selected applications each having different upper bound sequence lengths. We randomly selected an application from each of CBench categories (automotive, compression, telecom, consumer, office and network) since it was impractical to do this analysis with all applications. Having the upper bounds set to 3, 4, 5, 6 and 7 respectively, gives search spaces of 156, 781, 3909, 19k and 97k distinct permutations of sub-sequences with repetitions enabled (refer to Equation 1 for the optimization space). The /f_ive speedup lines show the trend of reaching a higher speedup value by iteratively exploring larger fraction of the optimization space. The maximum speedup found against -O3 using sequence lengths of 3, 4, 5, 6, and 7, respectively, are 1.23, 1.34, 1.38, 1.44 and 1.45. These results suggest to set the maximum length to 6 as this ensures achieving good speedups while avoiding a potential exploration of 100K sequences per each application in the training set. 3We provide harmonic mean rather than geometric mean as we are dealing with averaging speedups. Note that harmonic- mean is always less than or equal to geometric mean. ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:14 A. H. Ashouri et al. Table 5. List of the predictive models used in our experiments. Note that the proposed methodology is independent from any specific machine-learning algorithm (classifier) and it can be paired with any algorithm desired. Predictive Model Description MultilayerPerceptron (MLP) A feedforward arti/f_icial neural network model that maps sets of input data onto a set of appropri- ate outputs. A MLP consists of multiple layers of nodes in a directed graph, with each layer fully connected to the next one LinearRegression (LR) An approach for modeling the relationship between a scalar dependent variable y and one or more explanatory variables (or independent variables) denoted X. In linear regression, the relationships are modeled using linear predictor functions whose unknown model parameters are estimated from the data. KStar It is an instance-based classi/f_ier, that is the class of a test instance is based upon the class of those train- ing instances similar to it, as determined by some similarity function. It differs from other instance- based learners in that it uses an entropy-based distance function. Table 6. Average error rate for the proposed encoding function versus an arbitrary encoding M.L MiCOMP Encoding Arbitrary Encoding Improvement Factor MAE AE MAE AE MAE AE MLP 0.06778 0.05439 0.10826 0.11838 1.59× 2.16× LR 0.07515 0.07795 0.12879 0.13974 1.71× 1.79× KStar 0.05129 0.05078 0.09188 0.10866 1.77× 2.13× 4.5 MiCOMP’s Prediction Accuracy Unlike sequence prediction models [1, 6, 36] in speedup prediction approaches, prediction quality is measured by means of prediction error. This metric demonstrates how close the prediction values were to the actual speedups given the same sequence. We use the following different error measurement techniques. Mean Absolute Error. In statistics, the Mean Absolute Error (MAE) [18] is a quantity used to measure how close predictions are to the eventual outcomes. The mean absolute error is given by: MAE = 1 n nÕ i=1 |fi −/y.alti | (3) where we de/f_ineei as |fi −/y.alti |given fi as the prediction values and /y.alti the actual values. Consequently, the value ei is inverse proportional to the accuracy of the prediction. Approximation Error. Complementary to MAE, Approximation Error (AE) [40] is a common error mea- surement whereas in some data there is some discrepancy between an exact value and the approximation. An approximation error can occur because (i) certain measurements of the data are not precise (which we consider it can be the case for any computer scienti/f_ic measurement) and (ii) approximated values are used instead of the real values (the iterative prediction way keeps using the predicted values). It is calculated as: δ = |/uni03F5 | |/v.alt|= |/v.alt −/v.altapprox | |/v.alt| (4) where the absolute error is the magnitude of the difference between the exact value and the approximation. These de/f_initions can be extended to the case when/v.alt and /v.altapproximate are n-dimensional vectors, then by replacing the absolute error with an n-norm error. 4.5.1 Prediction Accuracy. We provide the prediction’s error rate in Table 6. We observe that the arbitrary encoding leads to higher error rates in the prediction values. . Table 6 shows that the KStar model does slightly better in terms of accuracy compared with other models, it achieves around 5% error rate on average. In general, having a smaller error rate does not always guarantee higher performance gain but rather showcases the accuracy of the prediction model to capture the correlation between different compiler sub-sequences and the speedup values. 4 4We are aware of the many other encoding possibilities that are more efficient (currently having N ×M length). However, we believe that extending the current encoding scheme to a more sophisticated version is out of scope of the work. Moreover, the proposed clustering technique can effectively reduce the number of N , thus the encoding scheme is scalable for higher orders. ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:15 Table 7. Best compiler optimization sub-sequences found using an exhaustive iterative compilation and their related speedups Application Best sub-sequence Speedup w.r.t. -O3 Kruskal-wallis p-value telecom_adpcm_c ECDDCC 1.35 0.9999 security_sha ACCACE 1.06 0.9934 security_blow/f_ish_e.csv BCCEEA 1.13 0.9909 automotive_susan_e.csv AABACA 1.15 0.9981 consumer_tiffdither DCEDCD 1.20 0.9999 security_rijndael_e CAEEC 1.10 0.9999 consumer_tiff2bw CCDCD 1.30 0.9999 bzip2e CBADCA 1.30 0.9944 automotive_susan_s ECCCDE 1.22 0.9999 office_stringsearch1 ABCBAC 1.07 0.9999 telecom_adpcm_d DCAACA 1.13 0.9939 consumer_jpeg_c DDC 1.41 0.9932 network_patricia CECBAA 1.18 0.9954 automotive_susan_c BDBCCB 1.32 0.9999 consumer_tiff2rgba DEDDC 1.32 0.9999 automotive_qsort1 CBAAAC 1.04 0.9969 security_blow/f_ish_d DACECA 1.09 0.9949 network_dijkstra EECBBE 1.51 0.9991 security_rijndael_d ECEACD 1.09 0.9992 bzip2d CBDACA 1.29 0.9994 automotive_bitcount BEACCA 1.19 0.9999 consumer_jpeg_d CCED 1.18 0.9999 consumer_tiffmedian BCBACB 1.15 0.9929 telecom_CRC32 DCAACA 1.26 0.9999 telecom_pgp_d DCAACA 1.21 0.9999 telecom_pgp_e DCA 1.22 0.9949 office_ispell ABEBAE 1.09 0.9999 office_ghostscript ABCBAC 1.08 0.9999 office_rsynth ABCBA 1.10 0.9969 consumer_mad DDCA 1.17 0.9999 consumer_lame DDCAB 1.15 0.9999 Harmonic mean 1.31 0.9976 4.5.2 Iterative Compilation Max Speedups. Iterative compilation is known to be able to achieve good performance results when compiling applications [ 9]. However, the approach is expensive and should be combined with more intelligent search algorithms [1, 6]. Table 7 reports the maximum speedups found by an iterative compilation approach using our proposed clustering while exploring the full optimization space exhaustively. This experiment empirically con/f_irms that the proposed clustering is useful on the phase-ordering space since we show that we can achieve on average a 31% speedup versus -O3. Figure 4 illustrates the trend when using MiCOMP sub-sequences with no baseline compared with having a baseline (e.g.: -O1, -O2 or -O3). The best optimization sequence for each of applications under-analysis and its speedup value are reported in the second and the third columns of Table 7. Readers can refer to Table 4 to /f_ind the exact set of compiler optimizations clustered in each sub-sequence. 4.6 Performance Gain of The MiCOMP Technique Against The Ranking Approach Our approach can improve the exploration to /f_ind the best optimization sequences in an optimization search space and to /f_ind the best speedups using a fewer number of predictions. Table 8 reports the comparison between the best speedup found by our approach and a state-of-the-art N-shot approach [34, 36]. The results, averaged using a Harmonic mean across all applications, show that using the same number of predictions from both models, our exploration technique can outperform the ranking approach on every number of predicted optimization sequences used (1, 5, 10, 15 and 20). This shows that our proposed methodology can effectively predicts the best compiler sequences to use and converges faster to better solutions in the space. 5 COMPARATIVE RESULTS In this section we evaluate the results of our model against three different techniques:(i) Standard optimization levels, (ii) Random Iterative Compilation (RIC) and, (iii) state-of-the-art prediction Models. We use our MiCOMP exploration policy and compare the performance of predictions to a previously published ranking approach [34, 35]. For each application under analysis, we tested the speedup gained using 1, 5 and 10 ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:16 A. H. Ashouri et al. Table 8. Prediction improvement of MiCOMP based on Adjusted Cosine Similarities against the Ranking (N-shot approach) Exploration Techniques Top-1 Top-5 Top-10 Top-15 Top-20 MiCOMP 1.01 1.06 1.09 1.10 1.12 Ranking 0.93 1.02 1.06 1.07 1.08 Table 9. MLP’s speedup table against LLVM’s-O3. Reported numbers are A (B% ): (A) speedup and (B) percentage speedup w.r.t. the optimal speedup value of exhaustive exploration. Values are reported for 1 prediction, 5 predictions and 10 predictions. Application 1 prediction 5 predictions 10 predictions automotive_bitcount 1.04 (95.38%) 1.07 (98.12%) 1.08 (98.92%) automotive_qsort1 1.01 (95.32%) 1.03 (96.93%) 1.03 (97.55%) automotive_susan_c 1.04 (96.61%) 1.06 (98.53%) 1.06 (99.07%) automotive_susan_e 1.04 (96.47%) 1.03 (98.41%) 1.04 (99.00%) automotive_susan_s 0.99 (96.26%) 1.01 (98.42%) 1.02 (98.98%) bzip2d 0.93 (92.77%) 0.96 (94.02%) 1.00 (94.37%) bzip2e 1.09 (83.77%) 1.10 (86.02%) 1.12 (90.37%) consumer_jpeg_c 1.01 (85.18%) 1.07 (90.35%) 1.10 (94.51%) consumer_jpeg_d 1.09 (84.70%) 1.14 (88.97%) 1.17 (97.85%) consumer_tiff2bw 0.96 (75.54%) 0.99 (80.59%) 1.02 (82.46%) consumer_tiff2rgba 0.91 (80.61%) 0.95 (86.19%) 1.07 (88.08%) consumer_tiffdither 1.02 (80.14%) 1.09 (85.86%) 1.11 (87.68%) consumer_tiffmedian 0.94 (79.21%) 1.02 (85.72%) 1.06 (89.31%) consumer_mad 1.02 (82.14%) 1.09 (85.86%) 1.11 (87.68%) consumer_lame 0.99 (89.21%) 1.02 (90.72%) 1.06 (92.31%) network_dijkstra 1.13 (60.00%) 1.29 (68.46%) 1.38 (73.00%) network_patricia 0.91 (74.99%) 0.93 (80.79%) 0.97 (93.91%) office_ispell 0.98 (84.99%) 1.01 (90.79%) 1.03 (93.91%) office_ghostscript 0.99 (79.99%) 1.03 (82.79%) 1.03 (90.91%) office_rsynth 1.01 (84.99%) 1.02 (90.79%) 1.03 (93.91%) office_stringsearch1 0.98 (64.99%) 1.02 (70.79%) 1.01 (73.91%) security_sha 0.93 (64.99%) 1.01 (70.79%) 1.03 (73.91%) security_blow/f_ish_e 0.97 (64.99%) 1.03 (70.79%) 1.03 (73.91%) security_blow/f_ish_d 0.97 (64.99%) 0.99 (70.79%) 1.02 (73.91%) security_rijndael_e 0.99 (64.99%) 1.02 (70.79%) 1.01 (73.91%) security_rijndael_d 1.00 (64.99%) 1.01 (70.79%) 1.04 (73.91%) telecom_adpcm_c 0.96 (64.99%) 1.01 (70.79%) 1.02 (73.91%) telecom_adpcm_d 0.98 (64.99%) 1.02 (70.79%) 1.01 (73.91%) telecom_gsm_d 0.93 (64.99%) 1.03 (70.79%) 1.04 (73.91%) telecom_CRC32 1.01 (85.18%) 1.07 (90.35%) 1.10 (94.51%) telecom_pgp_d 1.04 (96.61%) 1.06 (98.53%) 1.06 (99.07%) telecom_pgp_e 1.02 (80.14%) 1.09 (85.86%) 1.11 (87.68%) Harmonic mean 1.03 (84.74%) 1.05 (87.51%) 1.09 (91.52%) predictions and provide the Harmonic mean values. For example, one can see that for the network_dijkstra application we can gain a higher speedup values using MiCOMP and, on average even better than -O3 from just the /f_irst prediction. Moreover, we can achieve a 4% performance improvement over-O3 when we use 5 predicted optimization sequences from our model. Over all our benchmarks, using our model we can achieve 1%, 4%, and 9% speedups over -O3 using 1, 5, and 10 predicted optimization sequences, respectively. Consequently, our technique allows MiCOMP to outperform -O3 by high margins. 5.1 Comparison with Standard Optimization Levels Standard optimization levels have been introduced to achieve good performance on average. However, they come short of the customized auto-tuning frameworks per architecture/application/dataset. As we showed in Table 9, MiCOMP can surpass the performance of -O3 with a few predictions on application bases. Here we provide Table 10 which reports more /f_ine-grained speedup over all standard optimization levels. This demonstrates how fast (/f_irst number in the tuple) and in what percentage of the explored space (the second number), the framework is reaching a sequence which can outperform the speci/f_ic standard optimization level. Each column is reporting two values: (i) in how many predictions and (ii) in what percentage of the whole con/f_iguration space the propped methodology can outperformOX levels. ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:17 Table 10. Average Speedup w.r.t LLVM -O3. Numbers are A (B%): (A) How fast (in terms of number of predictions) in average the proposed methodology outperforms LLVM standard Optimizations. (B) The percentage of the optimization space explored to satisfy the goal. Predictive Modeling -O1 -O2 -O3 MultilayerPerceptron 1 (0.01%) 1 (0.01%) 2 (0.016%) LinearRegression 1 (0.01%) 1 (0.01%) 3 (0.02%) KStar 1 (0.01%) 1 (0.01%) 2 (0.016%) 5.2 Comparison with State-of-the-art Iterative Compilation Models In this section, we compare MiCOMP with two state-of-the-art intermediate-sequence prediction approaches proposed in [5, 24]. 5.2.1 Intermediate Speedup Comparison Case. (A).Kulkarni et al., [24] used Neuro-Evolution for Augmenting Topologies (NEAT) to predict the best compiler optimization to apply given the state of source-code being optimized by the dynamic JIT Jikes RVM compiler. . Contrary to the technique we propose in this paper where we obtain features of the code only once before it is optimized. Kulkarni et al. used NEAT, a machine-learning framework based on genetic evolution, to generate many neural-networks where each network was evaluated on the task of using static source code features to predict the next compiler optimization to apply. NEAT can make optimization predictions to any given maximum-length to predict the most bene/f_icial sequence of optimizations for the target application being compiled. In NEAT training time was reported around 10 days while the current approach requires a few hours to construct the model. Another advantage of the current work is the fact that it supports multiple predictions from the prediction-space while the NEAT approach can produce one-shot results based on the stop condition for each application and neural network con/f_iguration. We reproduced the work by Kulkarni et al. [24] by using 100 chromosomes and 500 generations on 12 core Xeon(R) CPU E5-1650 v2 @ 3.50GHz with 12GB running on Ubuntu and we report the result in Table 11. We ran NEAT in parallel with average running time of 1.75 hours per model (the longest took 4 hours). . The training and prediction is done with leave-one-out cross-validation in order to produce uniform results. . 5.2.2 Intermediate Speedup Comparison Case. (B).Ashouri et al. [5] demonstrated a predictive methodology to predict an intermediate speedup OF an optimization from the con/f_iguration space given the current state of the application. However, unlike [24], they employed dynamic features of the application under study. As mentioned in Section 5.2.1, a major downside in an intermediate speedup approach is that application feature should be collected on every state by means feature extraction and this makes the system impractical on large-scale data, specially, when dynamic features are collected on every state. In addition to an efficient feature collection process and predicting the complete optimization sequence to apply to the unoptimized code at once, MiCOMP brings two extensions to the aforementioned work. Second, comparison baseline in [5] was LLVM’s default optimization, while in this work we provide a comparison against LLVM’s -O3 (we show MiCOMP can outperform an aggressive optimization setting in LLVM, that is, -O3, in only a few predictions.). Figure 6 demonstrates the comparison. For this comparison, we used the same training data of up to the length of 4 (as it was declared in [5]) for both models to be uniform on both comparisons. We observe that, except the /f_irst two predictions, the proposed approach outperforms the intermediate speedup methodology reported in this work and on average MiCOMP brings 11% speedup gain. 5 10 15 20 25 30 35 40 45 50 number of extractions 0.0 0.2 0.4 0.6 0.8 1.0normalized speedup w.r.t O3 Proposed approach Immediate speedup predictor Fig. 6. Performance of MiCOMP w.r.t the performance of intermediate speedup predictor approach [5] ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:18 A. H. Ashouri et al. Table 11. Performance comparison of the single prediction by MiCOMP against the intermediate speedup approach reported in previous work [24]. All values are normalized by -O3. Application NEAT MiCOMP Best NN Size 1 prediction 1 prediction automotive_qsort1 1105 1.0336 1.0385 automotive_bitcount 1536 1.0923 1.0898 automotive_susan_c 607 1.0012 1.0491 automotive_susan_e 613 1.0211 1.0481 automotive_susan_s 1295 1.0135 1.0195 bzip2d 1159 1.0514 0.9898 bzip2e 1259 1.0012 0.9798 consumer_jpeg_c 1327 1.0205 1.1882 consumer_jpeg_e 596 1.0712 1.0981 consumer_tiff2bw 1038 0.9522 0.9491 consumer_tiff2rgba 1147 0.9905 0.9295 consumer_tiffdither 612 1.0222 1.0288 consumer_tiffmedian 1356 0.9097 0.9497 consumer_lame 1612 1.0221 1.0288 consumer_mad 1256 0.9097 0.9497 network_dijkstra 1343 1.0353 1.1382 network_patricia 622 0.7971 0.8585 office_ispell 1056 0.9197 0.9897 office_ghostscript 1356 0.9097 1.0997 office_rsynth 1306 0.9797 1.0497 office_stringsearch1 858 0.9897 1.0397 telecom_adpcm_c 958 0.9754 1.0192 telecom_adpcm_d 948 0.9897 1.0232 telecom_gsm_d 924 0.9997 1.0397 telecom_CRC32 886 0.9423 1.0012 telecom_pgp_d 843 0.9697 1.0234 telecom_pgp_e 1002 0.9891 1.0254 security_sha 1536 1.0193 1.0178 security_blow/f_ish_e 1221 1.0023 1.0298 security_blow/f_ish_d 1534 1.0923 1.0898 security_rijndael_e 1132 1.0113 1.0395 security_rijndael_d 1033 1.0123 1.0598 Harmonic Mean 0.9632 1.0295 5.3 Comparison with Random Iterative Optimization As we illustrated in Section 4.5.2, iterative compilation can improve application performance over standard compiler optimization sequences [ 1, 9]. Additionally, several published works have shown that drawing compiler optimization sequences at random can often be as good as using other more complicated search algorithms, such as genetic algorithms or simulated annealing [ 1, 10, 12]. In this section, we compare the effectiveness of MiCOMP to a Random Iterative Compilation (RIC) method that samples our clustered subse- quences from a uniform distribution. We randomized the distribution of predictions 10000 times to make sure the obtained model is totally uniform. The purpose of this comparison is to show how effective the MiComp predictive modeling works against random iterative compilation. Our results are presented in Figure 7. To present our results, we de/f_ineNormalized Performance Improvement (NPI) as the ratio of the performance improvement achieved over the potential performance improvement: N P I= Er ef −E Er ef −Ebest (5) where E is the execution time achieved by the methodology under consideration, Eref is the execution time achieved with a reference compilation methodology and Ebest is the best execution time that can be obtained through an exhaustive exploration of all possible compiler optimization sequences in the optimization space we are exploring. As the execution time E of the iterative compilation methodology under analysis gets closer to the reference execution time Eref , the value of NPI gets closer to 0, where 0 indicates no improvement was obtained. As E approaches the best execution time, Ebest , the value of NPI approaches 1. An NPI value of 1 indicates that the optimal performance available was achieved. The goal of the evaluation in this section is to show how effective MiCOMP is at exploring the optimization sequence space compared to RIC. . The X axis pertains to the number of predicted optimization sequences used and the Y axis shows their corresponding speedup values. We used NPI (scaled within [−∞, 1]) and the speedups are all normalized by ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:19 5 1 0 1 5 2 0 2 5 3 0 3 5 4 0 4 5 5 0 number of predictions 0 .0 0 .2 0 .4 0 .6 0 .8 1 .0normalized speedup w .r.t O3 Proposed Approach Random (a) Let both MiCOMP and random explore the opt. space 1-Shot 5-Shot 10-Shot 15-Shot 25-Shot 35-Shot 45-Shot 55-Shot 65-Shot 75-Shot 85-Shot 0.9 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 normalized speedup w.r.t -O3 number of predictions (b) Let only random explore the opt. space Fig. 7. MiCOMP performance comparison versus random iteration compilation -O3 performance. Thus, Y = 0 is the speedup line corresponding to -O3. We observe that the performance of MiCOMP outperforms Random Iterative Compilation with fairly a clear margin on each number of predicted optimization sequences used. Table 7 gives the the absolute speedup values. Figure 7b displays another result where we compare a /f_ixed number of predicted optimization sequences for MiCOMP, that is 5 predicted sequences, versus different number of predicted sequences from RIC. That is we observe the prediction quality of MiCOMP compared to different numbers of predicted optimization sequences drawn from a random distribution. Figure 7b depicts this scenario using a violin plot where the Y axis pertains to the speedup with respect to the RIC and the X axis corresponds to the different predicted optimization sequences obtained from RIC. Statistically, we observe that the quality of the 5-prediction of MiCOMP is as good as using 35 prediction optimization sequences from RIC thus we observe that the predicted optimization sequences derived by MiCOMP can give up to 7×exploration speedup versus the RIC method. 6 CONCLUSION We proposed and presented a clustering technique for all the compiler optimizations in LLVM’s -O3 and clustered them in /f_ive different optimization sub-sequences to speedup the training and exploration phase. This method helps us outperform LLVM’s -O3 optimization sequence. Moreover, MiCOMP has a simple encoding function that encodes an optimization sequence into a bit string, allowing us to apply standard machine learning techniques that require /f_ixed length feature vectors. We incorporated analogies between the analyzed problem and the context of Recommender Systems, and integrate similarity measures to boost exploration efficiency. We show that MiCOMP can outperform LLVM’s standard optimization levels with just a few predicted of optimizations sequences and achieves top 80% of the available speedup by traversing less than 5% of the optimization sequence space. . REFERENCES [1] Felix Agakov, Edwin Bonilla, John Cavazos, Björn Franke, Grigori Fursin, Michael FP O’Boyle, John Thomson, Marc Toussaint, and Christopher KI Williams. 2006. Using machine learning to focus iterative optimization. In Proceedings of the International Symposium on Code Generation and Optimization . IEEE Computer Society, 295–305. [2] Alan Agresti, I Liu, and others. 1999. Modeling a categorical variable allowing arbitrarily many category choices. Biometrics 55, 3 (1999), 936–943. [3] Amir Hossein Ashouri. 2012. Design space exploration methodology for compiler parameters in VLIW processors . Master’s thesis. Politecnico di Milano, Italy. http://hdl.handle.net/10589/72083. [4] Amir Hossein Ashouri. 2016. Compiler Autotuning Using Machine Learning Techniques . Ph.D. Dissertation. Politecnico di Milano, Italy. http://hdl.handle.net/10589/129561. [5] Amir Hossein Ashouri, Andrea Bignoli, Gianluca Palermo, and Cristina Silvano. 2016. Predictive Modeling Methodology for Compiler Phase-Ordering. In Proceedings of 7th Workshop on Parallel Programming and Run-Time Management Techniques for Many-core Architectures and 5th Workshop on Design Tools and Architectures for Multicore Embedded ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. 1:20 A. H. Ashouri et al. Computing Platforms . ACM. DOI:http://dx.doi.org/10.1145/2872421.2872424 [6] Amir Hossein Ashouri, Giovanni Mariani, Gianluca Palermo, Eunjung Park, John Cavazos, and Cristina Silvano. 2016. COBAYN: Compiler Autotuning Framework Using Bayesian Networks. ACM Trans. Archit. Code Optim. 13, 2, Article 21 (June 2016), 25 pages. DOI:http://dx.doi.org/10.1145/2928270 [7] Amir Hossein Ashouri, Giovanni Mariani, Gianluca Palermo, and Cristina Silvano. 2014. A Bayesian network approach for compiler auto-tuning for embedded processors. In Embedded Systems for Real-time Multimedia (ESTIMedia), 2014 IEEE 12th Symposium on . IEEE, 90–97. DOI:http://dx.doi.org/10.1109/ESTIMedia.2014.6962349 [8] Amir Hossein Ashouri, Vittorio Zaccaria, Sotirios Xydis, Gianluca Palermo, and Cristina Silvano. 2013. A framework for Compiler Level statistical analysis over customized VLIW architecture. In Very Large Scale Integration (VLSI-SoC), 2013 IFIP/IEEE 21st International Conference on . IEEE, 124–129. DOI:http://dx.doi.org/10.1109/VLSI-SoC.2013.6673262 [9] François Bodin, Toru Kisuki, Peter Knijnenburg, Mike O’Boyle, and Erven Rohou. 1998. Iterative compilation in a non-linear optimisation space. In Workshop on Pro/f_ile and Feedback-Directed Compilation. [10] John Cavazos, Grigori Fursin, Felix Agakov, Edwin Bonilla, Michael F. P. O’Boyle, and Olivier Temam. 2007. Rapidly Selecting Good Compiler Optimizations Using Performance Counters. In Proceedings of the International Symposium on Code Generation and Optimization (CGO ’07) . IEEE Computer Society, Washington, DC, USA, 185–197. DOI: http://dx.doi.org/10.1109/CGO.2007.32 [11] John Cavazos and J Eliot B Moss. 2004. Inducing heuristics to decide whether to schedule. In ACM SIGPLAN Notices , Vol. 39. ACM, 183–194. [12] Yang Chen, Shuangde Fang, Yuanjie Huang, Lieven Eeckhout, Grigori Fursin, Olivier Temam, and Chengyong Wu. 2012. Deconstructing iterative optimization. ACM Transactions on Architecture and Code Optimization (TACO) 9, 3 (2012), 21. [13] Keith D Cooper, Philip J Schielke, and Devika Subramanian. 1999. Optimizing for reduced code space using genetic algorithms. In ACM SIGPLAN Notices , Vol. 34. ACM, 1–9. [14] Grigori Fursin. 2010. Collective benchmark (cbench), a collection of open-source programs with multiple datasets assembled by the community to enable realistic benchmarking and research on program and architecture optimization. (2010). [15] Mark Hall, Eibe Frank, Geoffrey Holmes, Bernhard Pfahringer, Peter Reutemann, and Ian H Witten. 2009. The WEKA data mining software: an update. ACM SIGKDD explorations newsletter 11, 1 (2009), 10–18. [16] Torsten Hoe/f_ler and Roberto Belli. 2015. Scienti/f_ic benchmarking of parallel computing systems: twelve ways to tell the masses when reporting performance results. In Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis . ACM, 73. [17] Kenneth Hoste and Lieven Eeckhout. 2007. Microarchitecture-independent workload characterization. IEEE Micro 27, 3 (2007), 63–72. [18] Rob J Hyndman and Anne B Koehler. 2006. Another look at measures of forecast accuracy. International journal of forecasting 22, 4 (2006), 679–688. [19] Michael R Jantz and Prasad A Kulkarni. 2013. Exploiting phase inter-dependencies for faster iterative compiler optimization phase order searches. In Compilers, Architecture and Synthesis for Embedded Systems (CASES), 2013 International Conference on . IEEE, 1–10. [20] Kevin J Johnson and Robert E Synovec. 2002. Pattern recognition of jet fuels: comprehensive GC×GC with ANOVA- based feature selection and principal component analysis. Chemometrics and Intelligent Laboratory Systems 60, 1 (2002), 225–237. [21] Richard Arnold Johnson, Dean W Wichern, and others. 1992. Applied multivariate statistical analysis . Vol. 4. Prentice hall Englewood Cliffs, NJ. [22] Toru Kisuki, Peter M. W. Knijnenburg, and Michael F. P. O’Boyle. 2000. Combined Selection of Tile Sizes and Unroll Factors Using Iterative Compilation. In Proceedings of the 2000 International Conference on Parallel Architectures and Compilation Techniques (PACT’00), Philadelphia, Pennsylvania, USA, October 15-19, 2000 . 237–248. DOI:http: //dx.doi.org/10.1109/PACT.2000.888348 [23] Prasad A Kulkarni, David B Whalley, Gary S Tyson, and Jack W Davidson. 2009. Practical exhaustive optimization phase order exploration and evaluation. ACM Transactions on Architecture and Code Optimization (TACO) 6, 1 (2009), 1. [24] Sameer Kulkarni and John Cavazos. 2012. Mitigating the compiler optimization phase-ordering problem using machine learning. ACM SIGPLAN Notices 47, 10 (2012), 147–162. [25] David B Loveman. 1977. Program improvement by source-to-source transformation. Journal of the ACM (JACM) 24, 1 (1977), 121–145. [26] Chi-Keung Luk, Robert Cohn, Robert Muth, Harish Patil, Artur Klauser, Geoff Lowney, Steven Wallace, Vijay Janapa Reddi, and Kim Hazelwood. 2005. Pin: building customized program analysis tools with dynamic instrumentation. In Proceedings of the 2005 ACM SIGPLAN conference on Programming language design and implementation (PLDI ’05) . ACM, New York, NY, USA, 190–200. DOI:http://dx.doi.org/10.1145/1065010.1065034 [27] Luiz GA Martins, Ricardo Nobre, Joao MP Cardoso, Alexandre CB Delbem, and Eduardo Marques. 2016. Clustering- Based Selection for the Exploration of Compiler Optimization Sequences. ACM Transactions on Architecture and Code ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. MiCOMP: Mitigating the Compiler Phase-ordering Problem using Opt. Sub-sequences 1:21 Optimization (TACO) 13, 1 (2016), 8. [28] Antoine Monsifrot, François Bodin, and Rene Quiniou. 2002. A machine learning approach to automatic production of compiler heuristics. In Arti/f_icial Intelligence: Methodology, Systems, and Applications. Springer, 41–50. [29] J Eliot B Moss, Paul E Utgoff, John Cavazos, Doina Precup, Darko Stefanovic, Carla Brodley, and David Scheeff. 1997. Learning to schedule straight-line code. In NIPS, Vol. 97. 929–935. [30] Ricardo Nobre, Luiz GA Martins, and João MP Cardoso. 2015. Use of Previously Acquired Positioning of Optimizations for Phase Ordering Exploration. In Proceedings of the 18th International Workshop on Software and Compilers for Embedded Systems . ACM, 58–67. [31] Ricardo Nobre, Luiz GA Martins, and João MP Cardoso. 2016a. A graph-based iterative compiler pass selection and phase ordering approach. In Proceedings of the 17th ACM SIGPLAN/SIGBED Conference on Languages, Compilers, Tools, and Theory for Embedded Systems . ACM, 21–30. [32] Ricardo Nobre, Luıs Reis, and Joao MP Cardoso. 2016b. Compiler Phase Ordering as an Orthogonal Approach for Reducing Energy Consumption. In Proceedings of the 19th Workshop on Compilers for Parallel Computing (CPC2016), Valladolid, Spain, July 6–8, 2016 . [33] Holger Orup. 1999. On-the-/f_ly one-hot encoding of leading zero count. (Oct. 26 1999). US Patent 5,974,432. [34] EunJung Park, John Cavazos, and Marco A Alvarez. 2012. Using graph-based program characterization for predictive modeling. In Proceedings of the Tenth International Symposium on Code Generation and Optimization . ACM, 196–206. [35] Eunjung Park, John Cavazos, Louis-Noël Pouchet, Cédric Bastoul, Albert Cohen, and P Sadayappan. 2013. Predictive modeling in a polyhedral optimization space. International Journal of Parallel Programming 41, 5 (2013), 704–750. [36] Eunjung Park, Sameer Kulkarni, and John Cavazos. 2011. An evaluation of different modeling techniques for iterative compilation. In Proceedings of the 14th international conference on Compilers, architectures and synthesis for embedded systems. ACM, 65–74. [37] Suresh Purini and Lakshya Jain. 2013. Finding good optimization sequences covering program space.ACM Transactions on Architecture and Code Optimization (TACO) 9, 4 (2013), 56. [38] Badrul Sarwar, George Karypis, Joseph Konstan, and John Riedl. 2001. Item-based collaborative /f_iltering recommenda- tion algorithms. In Proceedings of the 10th international conference on World Wide Web . ACM, 285–295. [39] Satu Elisa Schaeffer. 2007. Graph clustering. Computer Science Review 1, 1 (2007), 27–64. [40] Steve Smale and Ding-Xuan Zhou. 2003. Estimating the approximation error in learning theory. Analysis and Applications 1, 01 (2003), 17–41. [41] Mark Stephenson, Saman Amarasinghe, Martin Martin, and Una-May O’Reilly. 2003. Meta Optimization: Improving Compiler Heuristics with Machine Learning. In Proceedings of the ACM SIGPLAN 2003 Conference on Programming Language Design and Implementation (PLDI ’03) . ACM, New York, NY, USA, 77–90. DOI:http://dx.doi.org/10.1145/ 781131.781141 [42] Steven R. Vegdahl. 1982. Phase coupling and constant generation in an optimizing microcode compiler.ACM SIGMICRO Newsletter 13, 4 (1982), 125–133. [43] Wei Zhang, Deli Zhao, and Xiaogang Wang. 2013. Agglomerative clustering via maximum incremental path integral. Pattern Recognition 46, 11 (2013), 3056–3065. ACM Transactions on Architecture and Code Optimization, Vol. , No. , Article 1. Publication date: September 2017. Using Machine Learning to Focus Iterative Optimization F. Agakov, E. Bonilla, J.Cavazos, B.Franke, G. Fursin, M.F.P. O'Boyle, J. Thomson, M. Toussaint, C.K.I. Williams School of Informatics University of Edinburgh UK Abstract Iterative compiler optimization has been shown to out- perform static approaches. This, however, is at the cost of large numbers of evaluations of the program. This paper de- velops a new methodology to reduce this number and hence speed up iterative optimization. It uses predictive modelling from the domain of machine learning to automatically focus search on those areas likely to give greatest performance. This approach is independent of search algorithm, search space or compiler infrastructure and scales gracefully with the compiler optimization space size. Off-line, a training set of programs is iteratively evaluated and the shape of the spaces and program features are modelled. These models are learnt and used to focus the iterative optimization of a new program. We evaluate two learnt models, an indepen- dent and Markov model, and evaluate their worth on two embedded platforms, the Texas Instrument C6713 and the AMD Au1500. We show that such learnt models can speed up iterative search on large spaces by an order of magni- tude. This translates into an average speedup of 1.22 on the TI C6713 and 1.27 on the AMD Au1500 in just 2 evalua- tions. 1 Introduction Using iterative search as a basis for compiler optimiza- tion has been widely demonstrated to give superior perfor- mance over static schemes [1, 3, 11]. The main drawback of these schemes is the amount of search time needed to achieve performance improvements given that each point of the search is a recompilation and execution of the pro- gram. Although multiple recompilations/executions are ac- ceptable for embedded code, libraries and persistent appli- cations, these long compilation/execution cycles restrict the space of options searched. On a larger scale, they are a sig- nicant barrier to adoption in general purpose compilation. There have been a number of papers focusing on reduc- ing the cost of iterative optimization. As a single evaluation consists of a compilation plus execution of the program, two recent papers have investigated reducing the cost of an indi- vidual compilation or execution [7]. In [1, 6] a more radical approach is used to reduce the total number of evaluations. Cooper et al [6] examine the structure of the search space, in particular the distribution of local minima relative to the global minima and devise new search based algorithms that outperform generic search techniques. An alternative ap- proach is developed in [20]. Here the space of compiler options is examined off-line on a per function basis and the best performing ones classied into a small tree of com- piler options. When compiling a new program, the tree is searched by compiling and executing the best path in the tree. As long as the best sequences can be categorized into a small tree, this proves to be a highly effective technique. This paper develops a new methodology to speed up it- erative optimization. It automatically focuses any search on those areas likely to give the greatest performance. This methodology is based on machine learning, is independent of search algorithm, search space or compiler infrastruc- ture and scales gracefully with the compiler optimization space size. It uses program features to correlate the pro- gram to be optimized with previous knowledge in order to focus the search. Off-line, a training set of programs is iter- atively evaluated and the shape of the spaces and program features are recorded. From this data, our scheme automat- ically learns a model which predicts those parts of the op- timization space that are likely to give good performance improvements for different classes of programs. When a new program is then encountered, an appropriate predictive model is selected, based on program features, which then biases the search to a certain area of the space. Using this technique we are able to speed up search by an up to an order of magnitude on large spaces. This paper is structured as follows. Section 2 provides a motivating example demonstrating how learning where to search can signicantly reduce the number of evaluations needed to nd good performance improvements. This is 1 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 86% 38% RANDOM FOCUSSED (a) (b) Figure 1. (a) Points corresponding to those transformation sequences whose performance is within 5 per cent of the optimum for adpcm on the TI C6713. The contour is the predicted area for good optimizations. (b) How close to the best performance random and focused search achieve for each program evaluation. The random algorithm achieves 38 % of the maximum improvement in 10 evalau- tions; the focused search 86%. followed in section 3 by a description of the experimental setup, an analysis of the optimization spaces encountered and an examination of how two standard search algorithms, random and genetic, perform. This is followed in section 4 by a description of two predictive models and a demonstra- tion of how they can be used to speed up search. Section 5 describes how the standard machine learning techniques of principal components analysis and nearest neighbors are used to learn the predictive models. In section 6, these learnt models are then tested on (i) a medium sized exhaustively enumerated space and (ii) a very large space, where they are shown to improve search performance by up to an or- der of magnitude. Section 7 describes related work and is followed in section 8 with some brief conclusions. 2 Motivation & Example This paper focuses on embedded applications where per- formance is critical and consequently there has been a large body of work aimed at improving the performance of opti- mizing compilers, e.g. [14]. Most of this work focuses on improving back-end, architecture specic compiler phases such as code generation, register allocation and schedul- ing. However, the investment in ever more sophisticated back-end algorithms produces diminishing returns. Iterative approaches based on back-end optimizations consequently give relatively small improvements [5]. In this paper, we consider source-level transformations [19, 8] for embedded systems. Such an approach is, by denition, highly portable from one processor to the next and provides additional ben- et to the manufacturer's highly tuned compiler. However, this portability comes at cost. For example, in [8], Franke et al require 1000 evaluations to achieve reasonable perfor- mance improvements. Search space The reason for this excessive search time is that determining the best high level sequence of transfor- mations for a particular program is non-trivial. Consider the diagram in gure 1 (a) showing the behavior of the adpcm program on the Texas Instrument's C6713. This diagram is an attempt at plotting all of the good performing points (within 5% of the optimum) in the space of all transforma- tions of length 5 selected from a set of 14 transformations. It therefore covers a space of size  . It is difcult to rep- resent a large 5 dimensional space graphically so each good performing transformation sequence (     is plotted at position   on the x-axis, which denotes prexes of length 2, and position     on the y axis, which denotes sufces of length 3. The most striking feature is that min- ima are scattered throughout the space and nding the very best is a difcult task. Prior knowledge about where good points were likely to be, could focus our search allowing the minimal point to be found faster. Alternatively, given a xed number of evaluations, we can expect improved per- formance if we know good areas to search within. 2 Focused search In this paper we develop a technique that learns off-line, ahead of time, a predictive model from iter- ative evaluations of other programs. This predictive model then denes good regions of the space to search. In gure 1 (a) the contour lines enclose those areas where our tech- nique predicts there will be good points. Using this predic- tion we are able to reduce the number of searches to achieve the same performance - rapidly reducing the cost of iterative search. This can be seen in gure 1 (b), which compares random search (averaged over 20 trials to be statistically meaningful) with and without the predictive model focus. The x-axis denotes (logarithmic scale) the number of evalu- ations performed by the search. The y-axis denotes the best performance achieved so far by the search ; 0% represents the original code performance, 100% the maximum perfor- mance achievable. It is immediately apparent that the pre- dictive model rapidly speedups up the search. For instance, after 10 evaluations, random searching achieves 38% of the potential improvement available while the focused search achieves 86%. As can be seen from gure 1 (b), such a large improvement would require over 80 evaluations using random search, justifying further investigation of predictive models. 3 Optimization Space This paper develops machine learning techniques to im- prove the search performance of iterative optimization. This section briey describes the benchmarks we use, the program transformations which make up the optimization space and the embedded platforms we evaluate. It then characterises the space and presents two standard search al- gorithms which are later used to show how learnt predictive models can dramatically speed up search.        Benchmarks The UTDSP [13, 17] benchmark suite was designed “to evaluate the quality of code generated by a high-level language (such as C) compiler targeting a pro- grammable digital signal processor (DSP)” [13]. This set of benchmarks contains small, but compute-intensive DSP kernels as well as larger applications composed of more complex algorithms. The size of programs ranges from 20- 500 lines of code where the runtime is usually below 1 sec- ond. However, these programs represent compute-intensive kernels widely regarded most important by DSP program- mers and are used indenitely in stream-processing appli- cations. Transformations In this paper we consider source to source transformations (Many of these transformations also appear within the optimisation phases of a native Label Transformation 1,2,3,4 Loop unrolling f Loop attening n FOR loop normalization t Non-perfectly nested loop conversion k Break load constant instructions s Common subexpression elimination d Dead code elimination h Hoisting of loop invariants i IF hoisting m Move loop-invariant conditionals c Copy propagation Table 1. The labeled transformations used for the exhaustive enumeration of the space. 1,2,3,4 corresponds to the loop unroll factor compiler[1]), applicable to C programs and available within the restructuring compiler SUIF 1 [10]. For the purpose of this paper, we have selected eleven transformations de- scribed and labeled in table 1. As we (arbitrarily) consider four loop unroll factors, this increases the number of trans- formations considered to 14. We then exhaustively evalu- ated all transformations sequences of length 5 selected from these 14 options. This allows us to evaluate the relative per- formance of our proposed techniques. In the later evalua- tion section (see section 7), we also consider searching, non exhaustively, a much larger space. Platforms Our experiments were performed on two dis- tinct platforms to demonstrate that our technique is generic. TI: The Texas Instrument C6713 is a high end oating point DSP. The wide clustered VLIW processor has 256kB of in- ternal memory. The programs were compiled using the TI's Code Composer Studio Tools Version 2.21 compiler with the highest -O3 optimization level and -ml3 ag (generates large memory model code). AMD: The AMD Alchemy Au1500 processor is an embedded SoC processor using a MIPS32 core (Au1), running at 500MHz. It has 16KB in- struction cache and 16KB non-blocking data cache. The programs were compiled with GCC 3.2.1 with the -O3 com- pile ag. According to the manufacturer, this version/option gives the best performance - better than later versions of GCC - and hence was used in our experiments. "! #%$& (') * +  ,-*$& ./ (' In order to characterize the optimization space, we ex- haustively enumerated all   transformation sequences on both platforms. Table 2 summarizes the performance avail- 3 TI AMD Prog. Improv. Seq. Improv. Seq. fft 3.64% 3nm 4.49% 4hns r 45.5% 4 26.7% 3 iir 16.3% 3h 29.5% h4 latnrm 0.34% nsch 27.1% csh4 lmsr 0.39% 1s 30.3% s3 mult 0.00%  30.5% 4 adpcm 24.0% 1ish 0.75% ism compress 39.1% 4s 24.0% hs4 edge 5.06% 3 23.1% ch4 histogram 0.00%  24.7% 4 lpc 10.7% sn2 6.01% h4cnm spectral 7.46% n4 8.53% sh4 Average 15.2% - 19.64% - Table 2. Summary of optimization space on the TI and AMD using exhaustive search able; columns 2 and 3 refer to the TI while columns 4 and 5 refer to the AMD respectively. Improved execution time The columns labeled Improv. (cols. 2 and 4) shows the maximum re- duction in execution time obtained on the TI and AMD within this exhaustively enumerated space. Eight (out of twelve) benchmarks for Texas Instruments and eleven (out of twelve) benchmarks for AMD achieved signicant improvement. The best execution time reduction was 45.5% on the TI and 30.5% on the AMD. On average, a 12.7% reduction was achieved for the TI and 13.8% for the AMD. This translates into an average speedup of 1.15 and 1.16 over the platform specic optimizing compiler. Best performing sequences The columns labeled Seq., (columns 3 and 5) in table 2 contain the best performing sequence for each benchmark on each machine. The indi- vidual letters within each entry refer to the labeled trans- formations in table 1, e.g. i = if hoisting. These en- tries show that the complexity and type of good transforma- tion sequences is program dependent. While benchmarks such as fir and edge detect for the TI and fir, mult and his- togram for the AMD reach their best performance with sin- gle transformations, other benchmarks such as adpcm for the TI and lpc for the AMD obtain their minimum execu- tion time with four and ve-length sequences respectively. Similarly, transformations that yield good performance on some benchmarks do not appear in the best sequences of other programs. For example, on the AMD the sequence ism makes adpcm run at its minimum execution time; however, none of these three individual transformations is present in the best performing sequence of compress. Critically, the best performing sequence on one program is never the best for another. Therefore, a technique which tries to simply apply the best sequence found on other pro- grams is unlikely to succeed.  . ( *'$ ,  $ - In this section, we describe two common methods used to search the transformation spaces: a blind random search (RA) and a “smarter” genetic algorithm (GA). Random search generates a random string of transformations where each transformation is equally likely to be chosen and per- forms surprisingly well in our experience. We congured our GA in the same manner as ”best” GA in [6] with an initial randomly selected population of 50. For the exhaustively enumerated space, both algorithms have similar performance as can be seen in gure 2. Here we plot the best performance achieved so far by each al- gorithm against how many program evaluations have been performed. This plot is averaged over all programs. Im- provements by either algorithm are more easily achieved on the TI due to the much greater number of sequences giving a signicant speedup. Both algorithms have similar overall performance with the GA performing well on the AMD in the early part of the search. However, random search performs better after a large number of evaluations as the GA appears to more likely to be stuck in local minima. In both cases, however, large numbers of evaluations are needed to gain any signif- icant performance improvements. In the next section we investigate how predictive models can speed up this search. 4 Models to focus search In order to speed up the search algorithm we wish to focus our attention on protable areas of the optimization space. We wish to build a model of those transformation sequences for which a program obtained good performance in the hope that this can be learnt and used on later pro- grams. We could simply record the best sequence achieved on other programs and hope that it improves our current program. However, this has a number of aws. Firstly, as the results in table 2 show, the best transformation on one program is never the best on others. Secondly, knowing the best sequence on another program only provides one single option and cannot guide subsequent search within a larger space. Alternatively, we can build intricate models that char- acterize the performance of all transformation sequences. Here the problem is that we can easily overt the model to the data so that it cannot be generalized to other programs. 4 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations RANDOM GA 0% 20% 40% 60% 80% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations RAND GA (a) TI (b) AMD Figure 2. Performance with respect to evaluations for the random (RAND) and genetic (GA) search algorithms on the TI (a) and AMD (b). The x-axis denotes (logarithmic scale) the number of evalu- ations performed by each search. The y-axis denotes the best performance achieved so far by the search; 0 % represents the original code performance, 100% the maximum performance achievable. Results averaged over all benchmarks Furthermore, such a complex model will require extensive training data, which may be costly to gather and is unre- alistic in practise. In this section we consider two differ- ent models which try to summarize the optimization space without excessive overtting. We consider (i) a simple inde- pendent distribution model and (ii) a more complex Markov model. Both of these require relatively small amounts of training data to construct and should be easy to learn (see section 5). &       ')    *          It makes sense to start with the simplest approach rst: modelling program transformations as if they were inde- pendent. We know that this assumption does not hold in general, but it might be sufcient to better focus search algorithms. Consider a set of  transformations       . Let    !" be a sequence of transformations  of length # , where each element %$ is cho- sen from the transformations in  . Under the independent model we assume that the probability of a sequence of trans- formations being good is simply the product of each of the individual transformations in the sequence being good, i.e.: &  %! '!"   " ( $*)  & $   (1) Here &  +  is the probability that the transformation ,+ oc- curs in good sequences. For our dataset we have chosen the set of good sequences to be those sequences that have an improvement in performance of at least - .0/ of the maxi- mum possible improvement. We calculate &  1+  by simply counting the number of times 1+ occurs in good sequences and normalize the distribution i.e. 2  $3)  &  +   . We then record within a vector the probability of each of the 4  transformations. For each benchmark we can build this probability vector or IID distribution. We refer to this as the IID-oracle. It is an oracle in the sense that we can only know its value once we have exhaustively enumerated the space, which in prac- tise is unrealistic. Our goal is to be able to predict this oracle by using machine learning techniques based on a training set of programs in order to improve search. However, it is necessary to prove rst that this oracle distribution does indeed lead to better search algorithms. &"! 5 ( 6 8795   As described above, the IID probability distribution function assumes that all transformations are mutually in- dependent neglecting the effect of interactions among trans- formations. This can be very restrictive, particularly when there are transformations that enable the applicability of other transformations or when some of them only yield good performance when others are applied. Therefore, in- cluding these interactions in our technique makes possible the construction of richer models that ideally will improve biased search algorithms and will obtain good performance in fewer evaluations. In order to keep the number of samples needed for build- ing our probability density function low while including in- 5 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 32% 75% 87% RANDOM IID-ORC MAR-ORC 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 27% 79% 88% GA GA-IID-ORC GA-MAR-ORC (a) TI: Random (b) TI: GA Figure 3. TI: Random (a) and GA (b) search versus IID-oracle and Markov oracle. Results averaged over all benchmarks teractions among transformations, we can take one step fur- ther from the IID distribution by using a Markov chain. A Markov chain for transformation sequences can be dened as follows: &    &    " ( $*) & $ $    The equation above states that the probability of a trans- formation applied in the sequence depends upon the trans- formations that have been applied before. The main as- sumption under this model is that these probabilities do not change along the sequence, i.e. they are the same at any position of the sequence, and therefore the model is often referred as a stationary Markov chain. This oversimplica- tion prevents the number of parameters of the model from increasing with the length of the sequences considered. Thus, the parameters of the model are the probability at the rst position of the sequence &    and the transi- tion matrix & $ $   with   ' # , which as be- fore can be learnt from data by counting. Once again 2  + )  &     +   and 2  + )  & $   + $    must be satised. As in section 4.1 the parameters of the model have been learnt from those sequences that have an improvement in performance at least - . / of the maximum possible im- provement. Using this model gives a 14 x 14 matrix. & ./  &,    ( *' $  7 &( &, $      $    To test the potential of our scheme, we compared each baseline search algorithm against this same algorithm us- ing each predictive model. For the random algorithm, in- stead of having a uniform probability of a transformation being selected, each model biases certain transformations over others. In the case of the GA, the initial population is selected based on the model's probabilities and then the GA is allowed to evolve as usual. We construct each model using the results obtained from searching a particular program's space and then test each model-enabled search algorithm on the same benchmark; we call these two learnt models: IID-oracle and Markov- oracle. These ”oracles” form an upper-bound on the perfor- mance we can expect to achieve when later trying to learn each model. This is to evaluate whether such models can improve the search. Clearly, if the best a model oracle can achieve is insignicant, it is not worth expending effort in trying to learn it. Figure 4 (a) depicts the average performance, over all our benchmarks, of the baseline random algorithm against random search biased with the two oracles on the TI. Sim- ilarly, Figure 4 (b) depicts the performance of the baseline GA algorithm versus using the two oracles to generate the initial population. In both gures, we see that the oracles can signicantly speed up nding a good solution. For ex- ample, at evaluation 10, randomachieves less than 20% of the maximum available performance. In contrast, random + IID-oracleachieves more than 50% of the available performance and random + Markov-oracleachieves around 80% of the performance. Figures 5 depicts a sim- ilar picture on the AMD architecture. On the AMD ar- chitecture, our two oracles signicantly improve the per- formance of each baseline algorithm. The baseline ran- dom search algorithm only achieves 4% of the available performance after 10 evaluations. In contrast, random + IID-oracle achieves about 20% of the available performance (5 times better than base) and random + Markov-oracle achieves 40% of the available perfor- 6 0% 20% 40% 60% 80% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 22% 41% 66% RAND IID-ORC MAR-ORC 0% 20% 40% 60% 80% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 22% 41% 72% GA GA-IID-ORC GA-MAR-ORC (a) AMD: Random (b) AMD: GA Figure 4. AMD: Random (a) and GA (b) search versus IID-oracle and Markov-oracle. Results averaged over all benchmarks mance, an order of magnitude better than the base random algorithm. On average, the baseline algorithm needs 100 evaluations to achieve the same performance as the base- line + the Markov oracle achieves with just 10 evaluations. We can see from these gures, that the IID and Markov models have the potential to dramatically improve the per- formance of both search algorithms. In the next section we describe how we can learn these models from previous off- line runs to build a predictive model. 5 Learning a model The biggest difculty in applying knowledge learnt off- line to a novel input is considering exactly which portions of this knowledge are relevant to the new program. We show that, as is the case in many other domains, programs can be successfully represented by program features, which can then be used to gauge their similarity and thus the applica- bility of previously learnt off-line knowledge. Obviously, the selection of these program features is crit- ical to the success of this method, and so we employ a well known statistical technique, principal component analysis (PCA) [2], to assist the selection. Initially, we identied thirty-six loop-level features we thought might describe the characteristics of a program well, and use them as input for the PCA process as shown in table 3. PCA tells us that, in this instance, due to redundancy and covariance in the fea- tures' values, these thirty-six features can be combined in such a way that they can be reduced to only ve features, whilst retaining 99% of the variance in the data. The output of this process is a 5-D feature vector for each benchmark, containing these ve condensed feature values. Nearest Neighbors By using a nearest neighbors classi- er [2], we can select which of our previously analyzed pro- grams our new program is most similar to. Learning using nearest neighbors is simply a matter of mapping each 5-D feature vector of our training programs (all our benchmarks) onto a 5-D feature space. Classification When a novel program is compiled, it is rst put through a feature extractor, and those features pro- cessed by PCA. The resulting 5-D feature vector is mapped onto the 5-D feature space, and the Euclidean distance be- tween it and every other point in the space calculated. The closest point is considered to be the 'nearest neighbor' and thus the program associated with that point is the most sim- ilar to the new program. We can apply this process to each of our twelve bench- marks by using leave-one-out cross-validation, where we disallow the use as training data of the feature vector asso- ciated with the program that is currently being evaluated, otherwise a program would always select itself as its near- est neighbor.Having selected a neighbor, a previously learnt probability distribution for that selected neighbor is then used as the model for the new program to be iteratively op- timized. /  7     ,  (   , It is useful to know how close our learnt distribution is to the oracle distribution for both models, IID and Markov. Averaged across all benchmarks, the learnt distribution achieves approximately 0/ of the performance per eval- uation of the IID-oracle and the Markov-oracle on the TI. On the AMD, we achieve a similar result - approximately 75 % of both oracles' performance. 7 Features for loop is simple? for loop is nested? for loop is perfectly nested? for loop has constant lower bound? for loop has constant upper bound? for loop has constant stride? for loop has unit stride? number of iterations in for loop loop step within for loop loop nest depth no, of array references within loop no. of instructions in loop no. of load instructions in loop no. of store instructions in loop no. of compare instructions in loop no. of branch instructions in loop no. of divide instructions in loop no. of noop instructions in loop no. of call instructions in loop no. of generic instructions in loop no. of array instructions in loop no. of memory copy instructions in loop no. of other instructions in loop no. of oat variables in loop no. of int variables in loop both int and oats used in loop? loop contains an if-construct? loop contains an if statement in for-construct? loop contains an if-construct? loop iterator is an array index? all loop indices are constants? array is accessed in a non-linear manner? loop strides on leading array dimensions only? loop has calls? loop has branches? loop has regular control ow? Table 3. Features used As the oracles have been shown to improve performance and we are able to achieve a signicant percentage of their improvement, this suggests that both learnt models should give signicant performance improvement over ex- isting schemes. This is evaluated in the next section. 6 Evaluation This section evaluates our focused search approach on two optimization spaces. The rst space is the exhaus- tively enumerated   space described throughout this pa- per. The second is a much larger space of size   i.e. transformation sequences of length 20 with each transfor- mation selected from one of 82 possible transformations available in SUIF 1 [10]. This was achieved using the stan- dard leave one out cross-validation scheme i.e. learn the IID and Markov models based on the training data from all other programs except for the one about to be optimized or tested   7       &$ & 7   / -      (' Initially, we ran both the baseline random and GA search algorithms for 500 program evaluations and recorded their speedup over time on both the TI and AMD. We then ran the same algorithms again, this time using the two learnt mod- els: IID and Markov. This was achieved using the standard leave one out cross-validation scheme i.e. learn the IID and Markov models based on the training data from all other programs except for the one about to be optimized or tested. The results for the TI and AMD are shown in gures 6 and 7 respectively. On the TI the learnt IID based mod- els achieve approximately twice the potential performance of either baseline algorithm after 10 evaluations (60%/62% vs 32%/27%) . The learnt Markov model does even better, achieving 79% of the perfomance available after the same number of evaluations. The baseline algorithms would need over 40 evaluations to achieve this same performance im- provement. On the AMD, the performance improvements are less dramatic, yet the learnt Markov based algorithms achieves more than twice the performance of the baseline algorithms after 10 evaluations. "!  7          ,  (' Experiments within an exhaustively enumerated space are useful as the performance of a search algorithm can be evaluated relative to the absolute minima. However, in prac- tise when we wish to search across a large range of transfor- mations, it is infeasible to run exhaustive experiments. In- stead we ran a random search for 1000 evaluations on each program space as off-line training data. This time we wish to focus on the performance achieved in the early parts of iterative optimization. So, we ran the baseline random search algorithm and both learnt models for just 50 evaluations. As the genetic algorithm and ran- dom search have the same behaviour for the rst 50 evalua- tions, the GA was not separately evaluated The speedups for each benchmark after 2, 5, 10 and 50 evaluations on the TI is shown in gure 7. Due to time constraints, only those benchmarks with non-negligible speedup on the exhaustively enumerated space are evalu- ated. The learnt models both deliver good performance and the random + IID learnt model achieves an average speedup of 1.26 after just 2 evaluations. Furthermore, the random + IID learnt model achieves a greater average performance af- ter 5 evaluations (1.34) than the baseline random algorithm does after 50 evaluations (1.29). Surprisingly, the IID learnt model achieves better perfor- mance than the Markov learnt model after 50 evaluations 1.41 vs 1.30 speedup in contrast to the results of the ex- haustively enumerated space (see gures 6 and 7). The rea- 8 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 32% 60% 79% RANDOM IID-LRN MAR-LRN 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 27% 62% 79% GA GA-IID-LRN GA-MAR-LRN (a) TI: Random (b) TI: GA Figure 5. TI: Random (a) and GA (b) search versus IID-learnt and Markov-learnt. Results averaged over all benchmarks 0% 20% 40% 60% 80% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 22% 35% 51% RAND IID-LRN MAR-LRN 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% 1 10 100 1000 Percent of Max Improvement Available Evaluations 17% 28% 44% GA GA-IID-LRN GA-MAR-LRN (a) AMD: Random (b) AMD: GA Figure 6. AMD: Random (a) and GA (b) search versus IID-learnt and Markov-learnt. Results averaged over all benchmarks son is that the Markov model needs a greater number of training evaluations than the IID model to model the space accurately. Here we have only 1000 evaluations to build a model. Similarly, the speedups for the AMD are shown for each benchmark after 2, 5, 10 and 50 evaluations on in gure 8. Again both learnt models signicantly outperform the base- line random algorithm. In fact the random + Markov learnt model achieves a greater average performance (1.33) after 5 evaluations than random does after 50 evaluations (1.32). It therefore achieves this level of performance an order of magnitude faster - the same is also true for the TI. Once again random + IID unexpectedly outperforms random + Markov at 50 evaluations. Thus after just 2 evaluations a speedup of 1.27 is found on average, almost three times the performance of the baseline algorithm. Finally, the single sequence that gives the best perfor- mance on average on the AMD in the small space is humc3. This gives an average speedup of 1.11, signicantly less than that achieved by random + Markov after just 2 eval- uations. On the TI, there does not exist a single sequence which gives any performance improvement on average. Discussion The Markov predictor performs less well on the exhaustive space due to the reduced amount of train- ing data. This suggests that the IID model should initially be used on a new platform when there is relatively small amounts of training data available. Over time, once suf- cient new data is accrued by iterative optimization, this can be used for a second stage of learning using the Markov 9 ` TI 2 Evaluations 5 Evaluations 10 Evaluations 50 Evaluations Benchmark R M I R M I R M I R M I fft 1.00 1.00 1.00 1.01 1.01 1.34 1.00 1.01 1.65 1.34 1.21 1.81 r 1.18 1.66 1.67 1.25 1.66 1.83 1.37 1.66 1.85 1.70 1.85 1.85 iir 1.14 1.20 1.19 1.18 1.23 1.19 1.19 1.23 1.21 1.19 1.23 1.23 adpm 1.08 1.33 1.17 1.18 1.33 1.18 1.25 1.35 1.24 1.28 1.43 1.28 edg 1.08 1.13 1.27 1.15 1.13 1.28 1.21 1.13 1.28 1.25 1.13 1.29 lpc 1.09 1.05 1.13 1.10 1.05 1.16 1.10 1.10 1.18 1.24 1.12 1.27 spe 1.01 1.10 1.15 1.03 1.17 1.16 1.05 1.17 1.16 1.07 1.17 1.18 AVG 1.08 1.21 1.22 1.12 1.22 1.34 1.16 1.23 1.36 1.29 1.30 1.41 Figure 7. Speedups up achieved by random search (R), random + Markov learnt model (M), random + IID learnt model (I) after 2, 5, 10 and 50 evaluations on each benchmark on the TI processor. Random + IID learnt model achieves greater average performance (1.34) after 5 evaluations than random does after 50 evaluations (1.29) model. 7 Related Work Iterative search-based optimization As well as the work of Almagor et al [1] and Triantafyllis et al [20] described in the introduction, there have been a number of related projects. A partially user-assisted approach to select opti- misation sequences for embedded applications is described in [11]. This approach combines user guides and perfor- mance information with a genetic algorithm to select lo- cal and global optimisation sequences. Other authors [9, 5] have explored ways to search program- or domain-specic command line parameters to enable and disable specic op- tions of various optimising compilers. In [8] iterative high level optimizations are applied to several embedded proces- sors using two probabilistic algorithms. Good speedups are obtained at the expense of very large number of evaluations. Finally, in [?], it is shown that carefully hand generated models can approach the performance of iterative optimi- sation. Machine Learning Machine learning predictive mod- elling has been recently used for non-search based optimisa- tion. Here the compiler attempts to learn off-line a good op- timization heuristic which is then used instead of the com- piler writer's hand-tuned method. Stephenson et al. [18] used genetic programming to tune heuristic priority functions for three compiler opti- mizations: within the Trimaran's IMPACT compiler. For two optimizations they achieved signicant improvements. However, these two pre-existing heuristics were not well implemented. Turning off data prefetching completely is preferable and reduces many of their signicant gains. For the third optimization, register allocation, they were only able to achieve on average a 2% increase over the manually tuned heuristic. Cavazos et al. [4] describe using supervised learning to control whether or not to apply instruction scheduling. No absolute performance improvements were reported how- ever. Finally, Monsifrot et al. [15] use a classier based on decision tree learning to determine which loops to unroll. They looked at the performance of compiling Fortran pro- grams from the SPEC benchmark suite using g77 for two different architectures, an UltraSPARC and an IA64 where there learnt scheme showed modest improvement. 8 Conclusion and Future Work This paper develops a new methodology to speed up it- erative compilation. It automatically focuses any search on those areas likely to give greatest performance. It use predictive modelling and program features to learn prof- itable areas of the optimization space to search. Experi- ments demonstrate that this approach is highly effective in speeding up iterative optimization. Currently, we have a one-off training/learning phase to build a model which is then applied to each new program. An obvious next step is to continuously update the learnt model after each new program is iteratively optimized, sim- ilar in spirit to lifelong compilation [12]. Future work will investigate different predictive models on new spaces to fur- ther improve the performance of search based optimization. 10 ` AMD 2 Evaluations 5 Evaluations 10 Evaluations 50 Evaluations Benchmark R M I R M I R M I R M I fft 1.00 1.04 1.04 1.00 1.05 1.07 1.00 1.07 1.10 1.00 1.15 1.17 r 1.22 1.33 1.46 1.28 1.44 1.51 1.37 1.44 1.54 1.48 1.55 1.94 iir 1.13 1.29 1.10 1.20 1.32 1.13 1.27 1.37 1.18 1.32 1.39 1.32 lat 1.04 1.48 1.40 1.23 1.53 1.43 1.32 1.53 1.52 1.41 1.53 1.53 lms 1.13 1.15 1.19 1.20 1.22 1.22 1.31 1.33 1.29 1.42 1.44 1.40 mul 1.05 1.54 1.85 1.26 1.89 1.88 1.48 1.89 1.90 1.69 1.92 1.93 adpcm 1.08 1.24 1.27 1.17 1.33 1.31 1.24 1.36 1.35 1.32 1.41 1.44 com 1.11 1.34 1.50 1.22 1.59 1.63 1.27 1.62 1.69 1.60 1.70 1.74 edg 1.10 1.11 1.20 1.21 1.16 1.25 1.29 1.26 1.30 1.32 1.31 1.34 his 1.08 1.27 1.16 1.21 1.31 1.29 1.28 1.32 1.33 1.33 1.33 1.36 lpc 1.00 1.00 1.05 1.00 1.02 1.09 1.00 1.04 1.13 1.06 1.09 1.23 spe 1.00 1.04 1.01 1.00 1.09 1.01 1.00 1.10 1.01 1.00 1.12 1.04 AVG 1.08 1.24 1.27 1.17 1.33 1.31 1.24 1.36 1.35 1.32 1.41 1.44 Figure 8. Speedups up achieved by random search (R), random + Markov learnt model (M), random + IID learnt model (I) after 2, 5, 10 and 50 evaluations on each benchmark on the AMD processor. Random + Markov learnt model achieves greater average performance (1.33) after 5 evaluations than random does after 50 evaluations (1.32) References [1] L. Almagor, K.D. Cooper, A. Grosul, T. J. Harvey, S. W. Reeves, D. Subramanian, L. Torczon and T. Waterman: Find- ing effective compilation sequences In LCTES 2004: 231- 239 [2] C. Bishop, Neural Networks for Pattern Recognition, OUP, 2005 [3] F. Bodin, T. Kisuki, P.M.W. Knijnenburg, M.F.P. O'Boyle, and E. Rohou. Iterative Compilation in a Non-Linear Op- timisation Space. Workshop on Pro®le Directed Feedback- Compilation, PACT'98, October 1998. [4] J. Cavazos and J. E.B. Moss, Inducing Heuristics to Decide Whether to Schedule, In ACM PLDI, May 2004. [5] K. Chow and Y. Wu. Feedback-directed selection and charac- terization of compiler optimizations. In (FDDO-4), Decem- ber 2001. [6] K. D. Cooper, A. Grosul, T.J. Harvey, S. Reeves, D. Subra- manian, L. Torczon, and T. Waterman. Searching for compi- lation sequences. Rice technical report, 2005. [7] K. D. Cooper, A. Grosul, T.J. Harvey, S. Reeves, D. Sub- ramanian, L. Torczon, and T. Waterman. ACME: adaptive compilation made efcient. In ACM LCTES, Chicago, IL, 2005. [8] B. Franke and M.F.P. O'Boyle, J. Thomson and G. Fursin. Probabilistic Source-Level Optimisation of Embedded Pro- grams In ACM LCTES 2005. [9] E.F. Granston and A. Holler. Automatic recommendation of compiler options. In (FDDO-4), December 2001. [10] M. Hall, L. Anderson, S. Amarasinghe, B. Murphy, S.W. Liao, E. Bugnion, M. and Lam. Maximizing multi- processor performance with the SUIF compiler. IEEE Com- puter, 29(12), 84–89, 1999 [11] P. Kulkarni, W. Zhao, H. Moon, K. Cho, D. Whalley, J. Davidson, M. Bailey, Y. Park, and K. Gallivan. Finding ef- fective optimization phase sequences. In ACM LCTES, June 2003. [12] C.Lattner and V.Adve, LLVM: a compilation framework for lifelong program analysis & transformation, In CGO, 2004. [13] C. Lee. UTDSP benchmark suite. http://www.eecg.toronto.edu/˜corinna/ DSP/infrastructure/UTDSP.html, 1998. [14] S.Liao, S. Devadas, K. Keutzer, A. Tjiang and A. Wang Op- timization Techniques for Embedded DSP Micro-processors In DAC, 1995. [15] A.Monsifrot, F.Bodin and R.Quiniou, A machine learning approach to automatic production of compiler heuristics, In International Conference on Arti®cial Intelligence: Method- ology, Systems, Applications, 2002. [16] K. Yotov, X.Li, G.Ren, M.Cibulskis, G. DeJong, M.Garzarn, D.Padua, K.Pingali, P.Stodghill, and P. Wu. A Comparison of Empirical and Model-driven Optimization. In PLDI 2003 [17] M. Saghir, P. Chow, and C. Lee. A comparison of traditional and VLIW DSP architecture for compiled DSP applications. In CASES '98, Washington, DC, USA, 1998. [18] M. Stephenson, S. Amarasinghe, M. Martin and U-M. O'Reilly Meta Optimization: Improving Compiler Heuris- tics with Machine Learning In PLDI 2003. [19] B. Su, J. Wang, and A. Esguerra. Source-level loop opti- mization for DSP code generation. In Proceedings of 1999 IEEE International Conference on Acoustic, Speech and Sig- nal Processing (ICASSP '99), volume 4, pages 2155–2158, Phoenix, AZ, 1999. [20] S. Triantafyllis, M. Vachharajani, N. Vachharajani, and D. I. August Compiler Optimization-Space Exploration In CGO March 2003. 11 OpenTuner: An Extensible Framework for Program Autotuning Jason Ansel Shoaib Kamil Kalyan Veeramachaneni Jonathan Ragan-Kelley Jeffrey Bosboom Una-May O’Reilly Saman Amarasinghe MIT - CSAIL August 27, 2014 1 / 30 Raytracer Example An example ray tracer program: raytracer.cpp $ g++ −O3 −o r a y t r a c e ra r a y t r a c e r . cpp $ time . / r a y t r a c e ra . / r a y t r a c e ra 0 . 1 7 s u s e r 0 . 0 0 s system 99% cpu 0.175 t o t a l 1.47x speedup with: $ g++ −O3 −o r a y t r a c e rb apps / r a y t r a c e r . cpp−f u n s a f e−math−o p t i m i z a t i o n s−fwrapv ↪→−fno −e x p e n s i v e−o p t i m i z a t i o n s−−param=max−p e e l−b r a n c h e s =115−fweb −fno − ↪→ cx−f o r t r a n−r u l e s−−param=max−i n l i n e−r e c u r s i v e−depth=25 −fno −btr −bb− ↪→ e x c l u s i v e−fno −t r e e−ch −−param=i v−max−c o n s i d e r e d−u s e s =69−f g c s e−l a s− ↪→ f t r e e−loop −d i s t r i b u t i o n−−param=max−goto −d u p l i c a t i o n−i n s n s =11−−param= ↪→ max−h o i s t−depth=44 −fs ch ed−s t a l l e d−i n s n s−dep −−param=max−once −p e e l e d− ↪→ i n s n s =165−−param=max−p i p e l i n e−r e g i o n−i n s n s =316−−param=i v−c o n s i d e r−a l l ↪→−c a n d i d a t e s−bound=75 $ time . / r a y t r a c e rb . / r a y t r a c e rb 0 . 1 2 s u s e r 0 . 0 0 s system 99% cpu 0.119 t o t a l 2 / 30 Raytracer Example An example ray tracer program: raytracer.cpp $ g++ −O3 −o r a y t r a c e ra r a y t r a c e r . cpp $ time . / r a y t r a c e ra . / r a y t r a c e ra 0 . 1 7 s u s e r 0 . 0 0 s system 99% cpu 0.175 t o t a l 1.47x speedup with: $ g++ −O3 −o r a y t r a c e rb apps / r a y t r a c e r . cpp−f u n s a f e−math−o p t i m i z a t i o n s−fwrapv ↪→−fno −e x p e n s i v e−o p t i m i z a t i o n s−−param=max−p e e l−b r a n c h e s =115−fweb −fno − ↪→ cx−f o r t r a n−r u l e s−−param=max−i n l i n e−r e c u r s i v e−depth=25 −fno −btr −bb− ↪→ e x c l u s i v e−fno −t r e e−ch −−param=i v−max−c o n s i d e r e d−u s e s =69−f g c s e−l a s− ↪→ f t r e e−loop −d i s t r i b u t i o n−−param=max−goto −d u p l i c a t i o n−i n s n s =11−−param= ↪→ max−h o i s t−depth=44 −fs ch ed−s t a l l e d−i n s n s−dep −−param=max−once −p e e l e d− ↪→ i n s n s =165−−param=max−p i p e l i n e−r e g i o n−i n s n s =316−−param=i v−c o n s i d e r−a l l ↪→−c a n d i d a t e s−bound=75 $ time . / r a y t r a c e rb . / r a y t r a c e rb 0 . 1 2 s u s e r 0 . 0 0 s system 99% cpu 0.119 t o t a l 2 / 30 Raytracer Example An example ray tracer program: raytracer.cpp $ g++ −O3 −o r a y t r a c e ra r a y t r a c e r . cpp $ time . / r a y t r a c e ra . / r a y t r a c e ra 0 . 1 7 s u s e r 0 . 0 0 s system 99% cpu 0.175 t o t a l 1.47x speedup with: $ g++ −O3 −o r a y t r a c e rb apps / r a y t r a c e r . cpp−f u n s a f e−math−o p t i m i z a t i o n s−fwrapv ↪→−fno −e x p e n s i v e−o p t i m i z a t i o n s−−param=max−p e e l−b r a n c h e s =115−fweb −fno − ↪→ cx−f o r t r a n−r u l e s−−param=max−i n l i n e−r e c u r s i v e−depth=25 −fno −btr −bb− ↪→ e x c l u s i v e−fno −t r e e−ch −−param=i v−max−c o n s i d e r e d−u s e s =69−f g c s e−l a s− ↪→ f t r e e−loop −d i s t r i b u t i o n−−param=max−goto −d u p l i c a t i o n−i n s n s =11−−param= ↪→ max−h o i s t−depth=44 −fs ch ed−s t a l l e d−i n s n s−dep −−param=max−once −p e e l e d− ↪→ i n s n s =165−−param=max−p i p e l i n e−r e g i o n−i n s n s =316−−param=i v−c o n s i d e r−a l l ↪→−c a n d i d a t e s−bound=75 $ time . / r a y t r a c e rb . / r a y t r a c e rb 0 . 1 2 s u s e r 0 . 0 0 s system 99% cpu 0.119 t o t a l 2 / 30 iv-consider-all-candidates-bound what??? This command is brittle and confusing: $ g++ −O3 −o r a y t r a c e rb apps / r a y t r a c e r . cpp−f u n s a f e−math−o p t i m i z a t i o n s−fwrapv ↪→−fno −e x p e n s i v e−o p t i m i z a t i o n s−−param=max−p e e l−b r a n c h e s =115−fweb −fno − ↪→ cx−f o r t r a n−r u l e s−−param=max−i n l i n e−r e c u r s i v e−depth=25 −fno −btr −bb− ↪→ e x c l u s i v e−fno −t r e e−ch −−param=i v−max−c o n s i d e r e d−u s e s =69−f g c s e−l a s− ↪→ f t r e e−loop −d i s t r i b u t i o n−−param=max−goto −d u p l i c a t i o n−i n s n s =11−−param= ↪→ max−h o i s t−depth=44 −fs ch ed−s t a l l e d−i n s n s−dep −−param=max−once −p e e l e d− ↪→ i n s n s =165−−param=max−p i p e l i n e−r e g i o n−i n s n s =316−−param=i v−c o n s i d e r−a l l ↪→−c a n d i d a t e s−bound=75 ▶ Specific to: ▶ raytracer.cpp ▶ Same flags are 1 .42x slower than -O1 for fft.c ▶ GCC 4.8.2-19ubuntu1 ▶ Intel Core i7-4770S ▶ Autotuners can help! 3 / 30 iv-consider-all-candidates-bound what??? This command is brittle and confusing: $ g++ −O3 −o r a y t r a c e rb apps / r a y t r a c e r . cpp−f u n s a f e−math−o p t i m i z a t i o n s−fwrapv ↪→−fno −e x p e n s i v e−o p t i m i z a t i o n s−−param=max−p e e l−b r a n c h e s =115−fweb −fno − ↪→ cx−f o r t r a n−r u l e s−−param=max−i n l i n e−r e c u r s i v e−depth=25 −fno −btr −bb− ↪→ e x c l u s i v e−fno −t r e e−ch −−param=i v−max−c o n s i d e r e d−u s e s =69−f g c s e−l a s− ↪→ f t r e e−loop −d i s t r i b u t i o n−−param=max−goto −d u p l i c a t i o n−i n s n s =11−−param= ↪→ max−h o i s t−depth=44 −fs ch ed−s t a l l e d−i n s n s−dep −−param=max−once −p e e l e d− ↪→ i n s n s =165−−param=max−p i p e l i n e−r e g i o n−i n s n s =316−−param=i v−c o n s i d e r−a l l ↪→−c a n d i d a t e s−bound=75 ▶ Specific to: ▶ raytracer.cpp ▶ Same flags are 1 .42x slower than -O1 for fft.c ▶ GCC 4.8.2-19ubuntu1 ▶ Intel Core i7-4770S ▶ Autotuners can help! 3 / 30 iv-consider-all-candidates-bound what??? This command is brittle and confusing: $ g++ −O3 −o r a y t r a c e rb apps / r a y t r a c e r . cpp−f u n s a f e−math−o p t i m i z a t i o n s−fwrapv ↪→−fno −e x p e n s i v e−o p t i m i z a t i o n s−−param=max−p e e l−b r a n c h e s =115−fweb −fno − ↪→ cx−f o r t r a n−r u l e s−−param=max−i n l i n e−r e c u r s i v e−depth=25 −fno −btr −bb− ↪→ e x c l u s i v e−fno −t r e e−ch −−param=i v−max−c o n s i d e r e d−u s e s =69−f g c s e−l a s− ↪→ f t r e e−loop −d i s t r i b u t i o n−−param=max−goto −d u p l i c a t i o n−i n s n s =11−−param= ↪→ max−h o i s t−depth=44 −fs ch ed−s t a l l e d−i n s n s−dep −−param=max−once −p e e l e d− ↪→ i n s n s =165−−param=max−p i p e l i n e−r e g i o n−i n s n s =316−−param=i v−c o n s i d e r−a l l ↪→−c a n d i d a t e s−bound=75 ▶ Specific to: ▶ raytracer.cpp ▶ Same flags are 1 .42x slower than -O1 for fft.c ▶ GCC 4.8.2-19ubuntu1 ▶ Intel Core i7-4770S ▶ Autotuners can help! 3 / 30 How to Autotune a Program Program 4 / 30 How to Autotune a Program Program Search Space Definition Run MethodExecutes 4 / 30 How to Autotune a Program Configuration Program Search Space Definition Run Method MeasurementExecutes Program Autotuner Machine Learning Search Technique(s) 4 / 30 How to Autotune a Program Configuration Program Search Space Definition Run Method MeasurementExecutes Program Autotuner Machine Learning Search Technique(s) Optimized Configuration 4 / 30 OpenTuner ▶ OpenTuner is an general framework for program autotuning ▶ Extensible configuration representation ▶ Uses ensembles of techniques to provide robustness to different search spaces ▶ As an example, lets implement a GCC flags autotuner with OpenTuner Search Space Definition Run Method (1) (2) 5 / 30 OpenTuner ▶ OpenTuner is an general framework for program autotuning ▶ Extensible configuration representation ▶ Uses ensembles of techniques to provide robustness to different search spaces ▶ As an example, lets implement a GCC flags autotuner with OpenTuner Search Space Definition Run Method (1) (2) 5 / 30 Define the Search Space with OpenTuner ▶ Optimization level: O0, O1, O2, O3 m a n i p u l a t o r =C o n f i g u r a t i o n M a n i p u l a t o r( ) m a n i p u l a t o r . addparameter ( I n t e g e r P a r a m e t e r( ’ o p tl e v e l ’ , 0 , 3) ) ▶ On/off flags, eg: ’-falign-functions’ vs ’-fno-align-functions’ GCC FLAGS = [ ’ a l i g n−f u n c t i o n s ’ , ’ a l i g n−jumps ’ , ’ a l i g n−l a b e l s ’ , ’ branch −count −r e g ’ , ’ branch−p r o b a b i l i t i e s ’ , # . . . (176 t o t a l ) ] f o r f l a gi n GCC FLAGS : m a n i p u l a t o r . addparameter ( EnumParameter ( f l a g , [ ’ on ’ , ’ o f f ’ , ’ d e f a u l t ’ ] ) ) ▶ Parameters, eg: ’--param early-inlining-insns=512’ # ( name , min , max) GCC PARAMS = [ ( ’ e a r l y−i n l i n i n g−i n s n s ’ , 0 , 1000) , ( ’ gcse−cost −d i s t a n c e−r a t i o ’ , 0 , 100) , # . . . (145 t o t a l ) ] f o r param , min val , max val i n GCC PARAMS : m a n i p u l a t o r . addparameter ( I n t e g e r P a r a m e t e r( param , min val , max val ) ) 6 / 30 Define the Search Space with OpenTuner ▶ Optimization level: O0, O1, O2, O3 m a n i p u l a t o r =C o n f i g u r a t i o n M a n i p u l a t o r( ) m a n i p u l a t o r . addparameter ( I n t e g e r P a r a m e t e r( ’ o p tl e v e l ’ , 0 , 3) ) ▶ On/off flags, eg: ’-falign-functions’ vs ’-fno-align-functions’ GCC FLAGS = [ ’ a l i g n−f u n c t i o n s ’ , ’ a l i g n−jumps ’ , ’ a l i g n−l a b e l s ’ , ’ branch −count −r e g ’ , ’ branch−p r o b a b i l i t i e s ’ , # . . . (176 t o t a l ) ] f o r f l a gi n GCC FLAGS : m a n i p u l a t o r . addparameter ( EnumParameter ( f l a g , [ ’ on ’ , ’ o f f ’ , ’ d e f a u l t ’ ] ) ) ▶ Parameters, eg: ’--param early-inlining-insns=512’ # ( name , min , max) GCC PARAMS = [ ( ’ e a r l y−i n l i n i n g−i n s n s ’ , 0 , 1000) , ( ’ gcse−cost −d i s t a n c e−r a t i o ’ , 0 , 100) , # . . . (145 t o t a l ) ] f o r param , min val , max val i n GCC PARAMS : m a n i p u l a t o r . addparameter ( I n t e g e r P a r a m e t e r( param , min val , max val ) ) 6 / 30 Define the Search Space with OpenTuner ▶ Optimization level: O0, O1, O2, O3 m a n i p u l a t o r =C o n f i g u r a t i o n M a n i p u l a t o r( ) m a n i p u l a t o r . addparameter ( I n t e g e r P a r a m e t e r( ’ o p tl e v e l ’ , 0 , 3) ) ▶ On/off flags, eg: ’-falign-functions’ vs ’-fno-align-functions’ GCC FLAGS = [ ’ a l i g n−f u n c t i o n s ’ , ’ a l i g n−jumps ’ , ’ a l i g n−l a b e l s ’ , ’ branch −count −r e g ’ , ’ branch−p r o b a b i l i t i e s ’ , # . . . (176 t o t a l ) ] f o r f l a gi n GCC FLAGS : m a n i p u l a t o r . addparameter ( EnumParameter ( f l a g , [ ’ on ’ , ’ o f f ’ , ’ d e f a u l t ’ ] ) ) ▶ Parameters, eg: ’--param early-inlining-insns=512’ # ( name , min , max) GCC PARAMS = [ ( ’ e a r l y−i n l i n i n g−i n s n s ’ , 0 , 1000) , ( ’ gcse−cost −d i s t a n c e−r a t i o ’ , 0 , 100) , # . . . (145 t o t a l ) ] f o r param , min val , max val i n GCC PARAMS : m a n i p u l a t o r . addparameter ( I n t e g e r P a r a m e t e r( param , min val , max val ) ) 6 / 30 Defining the Run Function ▶ Optimization level: O0, O1, O2, O3 d e f run ( s e l f , d e s i r e dr e s u l t , programinput , l i m i t ) : c f g = d e s i r e dr e s u l t . c o n f i g u r a t i o n . data gcc cmd = ’ g++ r a y t r a c e r . cpp−o . / tmp . b i n ’ gcc cmd += ’ −O{0}’ .format ( c f g [ ’ o p tl e v e l ’ ] ) ▶ On/off flags: f o r f l a gi n GCC FLAGS : i f c f g [ f l a g ] == ’ on ’ : gcc cmd += ’ −f {0}’ .format ( f l a g ) e l i f c f g [ f l a g ] == ’ o f f ’ : gcc cmd += ’ −fno −{0}’ .format ( f l a g ) ▶ Parameters: f o r param , min value , max value i n GCC PARAMS : gcc cmd += ’ −−param {0}={1}’ .format ( param , c f g [ param ] ) ▶ Measure how well it performs: c o m p i l er e s u l t = s e l f .c a l l p r o g r a m( gcc cmd ) r u nr e s u l t = s e l f .c a l l p r o g r a m( ’ . / tmp . b i n ’ ) r e t u r n R e s u l t ( time=r u nr e s u l t [ ’ time ’ ] ) 7 / 30 Defining the Run Function ▶ Optimization level: O0, O1, O2, O3 d e f run ( s e l f , d e s i r e dr e s u l t , programinput , l i m i t ) : c f g = d e s i r e dr e s u l t . c o n f i g u r a t i o n . data gcc cmd = ’ g++ r a y t r a c e r . cpp−o . / tmp . b i n ’ gcc cmd += ’ −O{0}’ .format ( c f g [ ’ o p tl e v e l ’ ] ) ▶ On/off flags: f o r f l a gi n GCC FLAGS : i f c f g [ f l a g ] == ’ on ’ : gcc cmd += ’ −f {0}’ .format ( f l a g ) e l i f c f g [ f l a g ] == ’ o f f ’ : gcc cmd += ’ −fno −{0}’ .format ( f l a g ) ▶ Parameters: f o r param , min value , max value i n GCC PARAMS : gcc cmd += ’ −−param {0}={1}’ .format ( param , c f g [ param ] ) ▶ Measure how well it performs: c o m p i l er e s u l t = s e l f .c a l l p r o g r a m( gcc cmd ) r u nr e s u l t = s e l f .c a l l p r o g r a m( ’ . / tmp . b i n ’ ) r e t u r n R e s u l t ( time=r u nr e s u l t [ ’ time ’ ] ) 7 / 30 Defining the Run Function ▶ Optimization level: O0, O1, O2, O3 d e f run ( s e l f , d e s i r e dr e s u l t , programinput , l i m i t ) : c f g = d e s i r e dr e s u l t . c o n f i g u r a t i o n . data gcc cmd = ’ g++ r a y t r a c e r . cpp−o . / tmp . b i n ’ gcc cmd += ’ −O{0}’ .format ( c f g [ ’ o p tl e v e l ’ ] ) ▶ On/off flags: f o r f l a gi n GCC FLAGS : i f c f g [ f l a g ] == ’ on ’ : gcc cmd += ’ −f {0}’ .format ( f l a g ) e l i f c f g [ f l a g ] == ’ o f f ’ : gcc cmd += ’ −fno −{0}’ .format ( f l a g ) ▶ Parameters: f o r param , min value , max value i n GCC PARAMS : gcc cmd += ’ −−param {0}={1}’ .format ( param , c f g [ param ] ) ▶ Measure how well it performs: c o m p i l er e s u l t = s e l f .c a l l p r o g r a m( gcc cmd ) r u nr e s u l t = s e l f .c a l l p r o g r a m( ’ . / tmp . b i n ’ ) r e t u r n R e s u l t ( time=r u nr e s u l t [ ’ time ’ ] ) 7 / 30 OpenTuner Results for GCC Flags 0.4 0.45 0.5 0.55 0.6 0 300 600 900 1200 1500 1800 Execution Time (seconds) Autotuning Time (seconds) g++ -O1 g++ -O2 g++ -O3 OpenTuner Autotune GCC flags for tsp ga.cpp. Median of 30 runs, error bars are 20th and 80th percentiles. 8 / 30 Related Projects A small selection of many related projects: Package Domain Search Method ATLAS Dense Linear AlgebraExhaustive Code Perforation Compiler Exhaustive + Simulated Annealing FFTW Fast Fourier TransformExhaustive / Dynamic Prog. OSKI Sparse Linear AlgebraExhaustive + Heuristic Active Harmony Runtime System Nelder-Mead PATUS Stencil ComputationsNelder-Mead or Evolutionary Sepya Stencil ComputationsRandom-Restart Gradient Ascent Dynamic Knobs Runtime System Control Theory Milepost GCC / cTuningCompiler IID Model + Central DB SEEC / Heartbeats Runtime System Control Theory Insieme Compiler Differential Evolution PetaBricks Programming LanguageBottom-up Evolutionary SPIRAL DSP Algorithms Pareto Active Learning ▶ Simple techniques (exhaustive, hill climbers, etc) are popular ▶ No single technique is best for all problems ▶ Representations are often just integers/floats/booleans 9 / 30 Related Projects A small selection of many related projects: Package Domain Search Method ATLAS Dense Linear AlgebraExhaustive Code Perforation Compiler Exhaustive + Simulated Annealing FFTW Fast Fourier TransformExhaustive / Dynamic Prog. OSKI Sparse Linear AlgebraExhaustive + Heuristic Active Harmony Runtime System Nelder-Mead PATUS Stencil ComputationsNelder-Mead or Evolutionary Sepya Stencil ComputationsRandom-Restart Gradient Ascent Dynamic Knobs Runtime System Control Theory Milepost GCC / cTuningCompiler IID Model + Central DB SEEC / Heartbeats Runtime System Control Theory Insieme Compiler Differential Evolution PetaBricks Programming LanguageBottom-up Evolutionary SPIRAL DSP Algorithms Pareto Active Learning ▶ Simple techniques (exhaustive, hill climbers, etc) are popular ▶ No single technique is best for all problems ▶ Representations are often just integers/floats/booleans 9 / 30 Limits of Current Approaches ▶ We believe simple techniques limit the scope and efficiency of autotuning ▶ A hill climber works great for a block size, but fails for more complex applications ▶ Many users of autotuning work hard to prune their search spaces to fit techniques such as exhaustive search ▶ Real problems have large search spaces 10 / 30 Limits of Current Approaches ▶ We believe simple techniques limit the scope and efficiency of autotuning ▶ A hill climber works great for a block size, but fails for more complex applications ▶ Many users of autotuning work hard to prune their search spaces to fit techniques such as exhaustive search ▶ Real problems have large search spaces 10 / 30 Over 10806 Combinations of GCC Optimizationsg++ apps/raytracer.cpp -o ./raytracerc -O3 -fno-align-functions -fno-align-loops -fasynchronous-unwind-tables -fbranch-count-reg -fbranch-probabilities-fno-branch-target-load-optimize -fbtr-bb-exclusive -fno-combine-stack-adjustments -fno-common -fcompare-elim -fcrossjumping -fcse-follow-jumps-fcx-fortran-rules -fcx-limited-range -fdata-sections -fno-dce -fdelete-null-pointer-checks -fno-devirtualize -fno-dse -fearly-inlining -fexceptions-ffinite-math-only -fforward-propagate -fgcse -fgcse-after-reload -fno-gcse-las -fno-graphite-identity -fno-if-conversion2 -fno-inline-functions-fno-inline-small-functions -fno-ipa-cp -fno-ipa-matrix-reorg -fno-ipa-profile -fno-ipa-pta -fipa-pure-const -fipa-reference -fno-ipa-sra -fno-ivopts-fno-loop-block -fno-loop-flatten -floop-interchange -fno-loop-parallelize-all -floop-strip-mine -fmath-errno -fno-merge-all-constants -fno-modulo-sched-fno-non-call-exceptions -fno-optimize-sibling-calls -fno-optimize-strlen -fpeel-loops -fpeephole -fno-peephole2 -fno-predictive-commoning-fno-prefetch-loop-arrays -fno-reg-struct-return -fno-regmove -frename-registers -fno-reorder-blocks -freorder-blocks-and-partition -freorder-functions-fno-rerun-cse-after-loop -fno-rounding-math -fno-rtti -fno-sched-critical-path-heuristic -fno-sched-dep-count-heuristic -fno-sched-group-heuristic-fno-sched-interblock -fno-sched-pressure -fsched-rank-heuristic -fsched-spec-insn-heuristic -fsched-spec-load -fno-sched-stalled-insns -fsched-stalled-insns-dep-fno-sched2-use-superblocks -fno-schedule-insns -fschedule-insns2 -fno-sel-sched-pipelining -fno-sel-sched-pipelining-outer-loops -fsel-sched-reschedule-pipelined-fno-short-wchar -fno-shrink-wrap -fsignaling-nans -fsingle-precision-constant -fno-split-ivs-in-unroller -fstrict-enums -fno-thread-jumps-ftrapping-math -fno-trapv -fno-tree-builtin-call-dce -fno-tree-ccp -fno-tree-copy-prop -ftree-copyrename -fno-tree-cselim -fno-tree-dce -ftree-dse-fno-tree-forwprop -ftree-fre -ftree-loop-distribute-patterns -fno-tree-loop-distribution -ftree-loop-if-convert -fno-tree-loop-if-convert-stores-fno-tree-loop-ivcanon -ftree-pta -fno-tree-reassoc -fno-tree-scev-cprop -fno-tree-slp-vectorize -ftree-sra -ftree-switch-conversion -fno-tree-ter-fno-tree-vectorize -ftree-vrp -fno-unit-at-a-time -fno-unroll-all-loops -fno-unroll-loops -funsafe-loop-optimizations -funwind-tables -fno-var-tracking-fvar-tracking-assignments-toggle -fno-var-tracking-uninit -fno-vect-cost-model -fno-vpt -fweb -fwhole-program -fwrapv --param=align-loop-iterations=16--param=align-threshold=28 --param=allow-load-data-races=1 --param=allow-packed-load-data-races=1 --param=allow-packed-store-data-races=0--param=allow-store-data-races=1 --param=case-values-threshold=3 --param=comdat-sharing-probability=14 --param=cxx-max-namespaces-for-diagnostic-help=1008--param=early-inlining-insns=19 --param=gcse-after-reload-critical-fraction=15 --param=gcse-after-reload-partial-fraction=10 --param=gcse-cost-distance-ratio=14--param=gcse-unrestricted-cost=5 --param=ggc-min-expand=66 --param=ggc-min-heapsize=15449 --param=graphite-max-bbs-per-function=248 --param=graphite-max-nb-scop-params=10--param=hot-bb-count-ws-permille=271 --param=hot-bb-frequency-fraction=2357 --param=inline-min-speedup=36 --param=inline-unit-growth=26 --param=integer-share-limit=511--param=ipa-cp-eval-threshold=222 --param=ipa-cp-loop-hint-bonus=18 --param=ipa-cp-value-list-size=18 --param=ipa-max-agg-items=13 --param=ipa-sra-ptr-growth-factor=6--param=ipcp-unit-growth=3 --param=ira-loop-reserved-regs=8 --param=ira-max-conflict-table-size=261 --param=ira-max-loops-num=25 --param=iv-always-prune-cand-set-bound=17--param=iv-consider-all-candidates-bound=26 --param=iv-max-considered-uses=85 --param=l1-cache-line-size=128 --param=l1-cache-size=24 --param=l2-cache-size=356--param=large-function-growth=237 --param=large-function-insns=4444 --param=large-stack-frame=431 --param=large-stack-frame-growth=250 --param=large-unit-insns=2520--param=lim-expensive=10 --param=loop-block-tile-size=40 --param=loop-invariant-max-bbs-in-loop=2500 --param=loop-max-datarefs-for-datadeps=816--param=lto-min-partition=261 --param=lto-partitions=96 --param=max-average-unrolled-insns=22 --param=max-completely-peel-loop-nest-depth=18--param=max-completely-peel-times=31 --param=max-completely-peeled-insns=325 --param=max-crossjump-edges=30 --param=max-cse-insns=251 --param=max-cse-path-length=8--param=max-cselib-memory-locations=1202 --param=max-delay-slot-insn-search=137 --param=max-delay-slot-live-search=84 --param=max-dse-active-local-stores=1250--param=max-early-inliner-iterations=2 --param=max-fields-for-field-sensitive=0 --param=max-gcse-insertion-ratio=50 --param=max-gcse-memory=13107200--param=max-goto-duplication-insns=15 --param=max-grow-copy-bb-insns=23 --param=max-hoist-depth=101 --param=max-inline-insns-auto=43 --param=max-inline-insns-recursive=126--param=max-inline-insns-recursive-auto=135 --param=max-inline-insns-single=421 --param=max-inline-recursive-depth=24 --param=max-inline-recursive-depth-auto=28--param=max-iterations-computation-cost=24 --param=max-iterations-to-track=253 --param=max-jump-thread-duplication-stmts=21 --param=max-last-value-rtl=2794--param=max-modulo-backtrack-attempts=14 --param=max-once-peeled-insns=105 --param=max-partial-antic-length=25 --param=max-peel-branches=84--param=max-peel-times=23 --param=max-peeled-insns=25 --param=max-pending-list-length=10 --param=max-pipeline-region-blocks=44 --param=max-pipeline-region-insns=578--param=max-predicted-iterations=28 --param=max-reload-search-insns=356 --param=max-sched-extend-regions-iters=1 --param=max-sched-insn-conflict-delay=1--param=max-sched-ready-insns=101 --param=max-sched-region-blocks=15 --param=max-sched-region-insns=36 --param=max-slsr-cand-scan=12 --param=max-stores-to-sink=2--param=max-tail-merge-comparisons=24 --param=max-tail-merge-iterations=1 --param=max-tracked-strlens=351 --param=max-unroll-times=26 --param=max-unrolled-insns=570--param=max-unswitch-insns=17 --param=max-unswitch-level=11 --param=max-variable-expansions-in-unroller=0 --param=max-vartrack-expr-depth=14--param=max-vartrack-reverse-op-size=15 --param=max-vartrack-size=12500164 --param=min-crossjump-insns=18 --param=min-inline-recursive-probability=9--param=min-insn-to-prefetch-ratio=23 --param=min-spec-prob=15 --param=min-vect-loop-bound=2 --param=omega-eliminate-redundant-constraints=0--param=omega-hash-table-size=138 --param=omega-max-eqs=43 --param=omega-max-geqs=68 --param=omega-max-keys=378 --param=omega-max-vars=32--param=omega-max-wild-cards=55 --param=partial-inlining-entry-probability=68 --param=predictable-branch-outcome=0 --param=prefetch-latency=115--param=prefetch-min-insn-to-mem-ratio=2 --param=sccvn-max-alias-queries-per-access=2543 --param=sccvn-max-scc-size=2504 --param=scev-max-expr-complexity=32--param=scev-max-expr-size=45 --param=sched-mem-true-dep-cost=0 --param=sched-pressure-algorithm=1 --param=sched-spec-prob-cutoff=79 --param=sched-state-edge-prob-cutoff=2--param=selsched-insns-to-rename=6 --param=selsched-max-lookahead=14 --param=selsched-max-sched-times=1 --param=simultaneous-prefetches=9--param=sink-frequency-threshold=53 --param=slp-max-insns-in-bb=279 --param=sms-dfa-history=3 --param=sms-loop-average-count-threshold=2--param=sms-max-ii-factor=35 --param=sms-min-sc=3 --param=ssp-buffer-size=13 --param=switch-conversion-max-branch-ratio=2 --param=tm-max-aggregate-size=32--param=tracer-dynamic-coverage=66 --param=tracer-dynamic-coverage-feedback=46 --param=tracer-max-code-growth=200 --param=tracer-min-branch-probability=82--param=tracer-min-branch-probability-feedback=70 --param=tracer-min-branch-ratio=21 --param=tree-reassoc-width=2 --param=uninit-control-dep-attempts=415--param=use-canonical-types=0 --param=vect-max-version-for-alias-checks=11 --param=vect-max-version-for-alignment-checks=23 11 / 30 Large Search Spaces are a Challenge Project Benchmark Possible Configurations GCC/G++ Flags all 10806 Halide Blur 1025 Halide Wavelet 1032 Halide Bilateral 10176 HPL n/a 109.9 PetaBricks Poisson 103657 PetaBricks Sort 1090 PetaBricks Strassen 10188 PetaBricks TriSolve 101559 Stencil all 106.5 Unitary n/a 1021 Mario n/a 106328 12 / 30 Ensembles of Techniques ▶ OpenTuner contains many techniques such as: ▶ Differential Evolution ▶ Genetic Algorithms ▶ Greedy Mutation ▶ Multi-armed Bandit ▶ Nelder Mead ▶ Partial Swarm Optimization ▶ Pattern Search ▶ Pseudo Annealing ▶ Torczon ▶ Uses ensembles of techniques to provide robustness to different search spaces 13 / 30 Ensembles of Techniques in OpenTuner Differential Evolution Particle Swarm Optimization Torczon Hill Climber 14 / 30 Ensembles of Techniques in OpenTuner Differential Evolution Particle Swarm Optimization Torczon Hill Climber Information sharing through ResultsDB 14 / 30 Ensembles of Techniques in OpenTuner Differential Evolution Particle Swarm Optimization Torczon Hill Climber Information sharing through ResultsDB AUC Bandit 14 / 30 Ensembles of Techniques in OpenTuner Differential Evolution Particle Swarm Optimization Torczon Hill Climber Information sharing through ResultsDB AUC Bandit Which configuration should we try next? ? 14 / 30 Ensembles of Techniques in OpenTuner Differential Evolution Particle Swarm Optimization Torczon Hill Climber Information sharing through ResultsDB AUC Bandit Which configuration should we try next? 33% Exploration 33% 33% 14 / 30 Ensembles of Techniques in OpenTuner Differential Evolution Particle Swarm Optimization Torczon Hill Climber Information sharing through ResultsDB AUC Bandit Which configuration should we try next? 100% Exploitation 0% 0% 14 / 30 OpenTuner’s General Representation ▶ Large search spaces do not mean haphazard ones ▶ Choosing the right representation is critical ▶ OpenTuner allows programmers to easily express structured search spaces ▶ Supports complex parameter types such as permutations, schedules, mappings ▶ User defined parameter types ▶ Next, a demonstration of the versatility of OpenTuner 15 / 30 OpenTuner’s General Representation ▶ Large search spaces do not mean haphazard ones ▶ Choosing the right representation is critical ▶ OpenTuner allows programmers to easily express structured search spaces ▶ Supports complex parameter types such as permutations, schedules, mappings ▶ User defined parameter types ▶ Next, a demonstration of the versatility of OpenTuner 15 / 30 OpenTuner Can Play Super Mario Bros! (Video 1) 1http://youtu.be/pTi_tHpj6Ow 16 / 30 OpenTuner Can Play Super Mario Bros! ▶ Only feedback is number of pixels moved to the right ▶ e.g. approximately 1500 pixels for first pit ▶ OpenTuner doesn’t see the screen ▶ Super Mario Bros is deterministic, single run suffices 17 / 30 Naive Representation ▶ Bad, because most configurations make no sense. ▶ Just mashing random buttons. ▶ Doesn’t work at all (Video 2). 2http://youtu.be/nyYdq1jJQrw 18 / 30 Naive Representation ▶ Bad, because most configurations make no sense. ▶ Just mashing random buttons. ▶ Doesn’t work at all (Video 2). 2http://youtu.be/nyYdq1jJQrw 18 / 30 Better Representation ▶ Movements (list): ▶ Direction (left, right, run left, or run right) ▶ Duration (frames) ▶ Jumps (list): ▶ Start frame ▶ Duration (frames) Choosing the right representation is critical ▶ Search space size 10 6328 ▶ Winning run found in 13641 ( ≈ 104) attempts ▶ Under 5 minutes of training time 19 / 30 Better Representation ▶ Movements (list): ▶ Direction (left, right, run left, or run right) ▶ Duration (frames) ▶ Jumps (list): ▶ Start frame ▶ Duration (frames) Choosing the right representation is critical ▶ Search space size 10 6328 ▶ Winning run found in 13641 ( ≈ 104) attempts ▶ Under 5 minutes of training time 19 / 30 Better Representation ▶ Movements (list): ▶ Direction (left, right, run left, or run right) ▶ Duration (frames) ▶ Jumps (list): ▶ Start frame ▶ Duration (frames) Choosing the right representation is critical ▶ Search space size 10 6328 ▶ Winning run found in 13641 ( ≈ 104) attempts ▶ Under 5 minutes of training time 19 / 30 Super Mario Bros Results 1000 1500 2000 2500 3000 3500 0 60 120 180 240 300 Pixels Moved Right (Progress) Autotuning Time (seconds) Win Level OpenTuner 20 / 30 OpenTuner Generating Halide Schedules ▶ A domain specific language for image processing and photography ▶ Used for camera pipeline in Google Glass, HDR+ in Android, some filters in Photoshop ▶ Separate algorithm language and scheduling language ▶ We use OpenTuner to generate the scheduling language 21 / 30 Simple Halide Example Algorithm: ImageParam i n p u t (UInt ( 1 6 ) , 2) ; Func a ( ”a” ) , a ( ”b” ) , a ( ” c ” ) ; Var x ( ” x ” ) , y ( ” y ” ) ; a ( x , y ) = i n p u t ( x , y ) ; b ( x , y ) = a ( x , y ) ; c ( x , y ) = b ( x , y ) ; Complex schedules: ▶ Split ▶ Reorder / reorder storage ▶ Vectorize / Parallel ▶ Compute at / compute root OpenTuner Generated Schedule: Var x0 , y1 , x2 , x4 , y5 ; a . s p l i t( x , x , x0 , 4) . s p l i t( y , y , y1 , 16) . r e o r d e r( y1 , x0 , y , x ) . v e c t o r i z e( y1 , 4) . compute at ( b , y ) ; b . s p l i t( x , x , x2 , 64) . r e o r d e r( x2 , x , y ) . r e o r d e rs t o r a g e( y , x ) . v e c t o r i z e( x2 , 8) . compute at ( c , x4 ) ; c . s p l i t( x , x , x4 , 8) . s p l i t( y , y , y5 , 2) . r e o r d e r( x4 , y5 , y , x ) . p a r a l l e l( x ) . compute root ( ) ; 22 / 30 Simple Halide Example Algorithm: ImageParam i n p u t (UInt ( 1 6 ) , 2) ; Func a ( ”a” ) , a ( ”b” ) , a ( ” c ” ) ; Var x ( ” x ” ) , y ( ” y ” ) ; a ( x , y ) = i n p u t ( x , y ) ; b ( x , y ) = a ( x , y ) ; c ( x , y ) = b ( x , y ) ; Complex schedules: ▶ Split ▶ Reorder / reorder storage ▶ Vectorize / Parallel ▶ Compute at / compute root OpenTuner Generated Schedule: Var x0 , y1 , x2 , x4 , y5 ; a . s p l i t( x , x , x0 , 4) . s p l i t( y , y , y1 , 16) . r e o r d e r( y1 , x0 , y , x ) . v e c t o r i z e( y1 , 4) . compute at ( b , y ) ; b . s p l i t( x , x , x2 , 64) . r e o r d e r( x2 , x , y ) . r e o r d e rs t o r a g e( y , x ) . v e c t o r i z e( x2 , 8) . compute at ( c , x4 ) ; c . s p l i t( x , x , x4 , 8) . s p l i t( y , y , y5 , 2) . r e o r d e r( x4 , y5 , y , x ) . p a r a l l e l( x ) . compute root ( ) ; 22 / 30 Simple Halide Example Algorithm: ImageParam i n p u t (UInt ( 1 6 ) , 2) ; Func a ( ”a” ) , a ( ”b” ) , a ( ” c ” ) ; Var x ( ” x ” ) , y ( ” y ” ) ; a ( x , y ) = i n p u t ( x , y ) ; b ( x , y ) = a ( x , y ) ; c ( x , y ) = b ( x , y ) ; Complex schedules: ▶ Split ▶ Reorder / reorder storage ▶ Vectorize / Parallel ▶ Compute at / compute root OpenTuner Generated Schedule: Var x0 , y1 , x2 , x4 , y5 ; a . s p l i t( x , x , x0 , 4) . s p l i t( y , y , y1 , 16) . r e o r d e r( y1 , x0 , y , x ) . v e c t o r i z e( y1 , 4) . compute at ( b , y ) ; b . s p l i t( x , x , x2 , 64) . r e o r d e r( x2 , x , y ) . r e o r d e rs t o r a g e( y , x ) . v e c t o r i z e( x2 , 8) . compute at ( c , x4 ) ; c . s p l i t( x , x , x4 , 8) . s p l i t( y , y , y5 , 2) . r e o r d e r( x4 , y5 , y , x ) . p a r a l l e l( x ) . compute root ( ) ; 22 / 30 Simple Halide Example Algorithm: ImageParam i n p u t (UInt ( 1 6 ) , 2) ; Func a ( ”a” ) , a ( ”b” ) , a ( ” c ” ) ; Var x ( ” x ” ) , y ( ” y ” ) ; a ( x , y ) = i n p u t ( x , y ) ; b ( x , y ) = a ( x , y ) ; c ( x , y ) = b ( x , y ) ; Complex schedules: ▶ Split ▶ Reorder / reorder storage ▶ Vectorize / Parallel ▶ Compute at / compute root OpenTuner Generated Schedule: Var x0 , y1 , x2 , x4 , y5 ; a . s p l i t( x , x , x0 , 4) . s p l i t( y , y , y1 , 16) . r e o r d e r( y1 , x0 , y , x ) . v e c t o r i z e( y1 , 4) . compute at ( b , y ) ; b . s p l i t( x , x , x2 , 64) . r e o r d e r( x2 , x , y ) . r e o r d e rs t o r a g e( y , x ) . v e c t o r i z e( x2 , 8) . compute at ( c , x4 ) ; c . s p l i t( x , x , x4 , 8) . s p l i t( y , y , y5 , 2) . r e o r d e r( x4 , y5 , y , x ) . p a r a l l e l( x ) . compute root ( ) ; 22 / 30 Simplified Schedules (Placement Only) Schedule: a.compute at(b, y) b.compute at(c, x) c.compute root() Logical Loop Structure: for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() Resulting Code: for x: for y: tmp a = input[x, y] tmp b[y] = tmp a for y: output[x, y] = tmp b[y] 23 / 30 Simplified Schedules (Placement Only) Schedule: a.compute at(b, y) b.compute at(c, x) c.compute root() Logical Loop Structure: for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c()Resulting Code: for x: for y: tmp a = input[x, y] tmp b[y] = tmp a for y: output[x, y] = tmp b[y] 23 / 30 Simplified Schedules (Placement Only) Schedule: a.compute at(b, y) b.compute at(c, x) c.compute root() Logical Loop Structure: for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() Resulting Code: for x: for y: tmp a = input[x, y] tmp b[y] = tmp a for y: output[x, y] = tmp b[y] 23 / 30 Simplified Schedules (Placement Only) Schedule: a.compute at(b, y) b.compute at(c, x) c.compute root() Logical Loop Structure: for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() Resulting Code: for x: for y: tmp a = input[x, y] tmp b[y] = tmp a for y: output[x, y] = tmp b[y] 23 / 30 Simplified Schedules (Placement Only) Schedule: a.compute at(b, y) b.compute at(c, x) c.compute root() Logical Loop Structure: for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() Resulting Code: for x: for y: tmp a = input[x, y] tmp b[y] = tmp a for y: output[x, y] = tmp b[y] 23 / 30 Simplified Schedules (Placement Only) Schedule: a.compute at(b, y) b.compute at(c, x) c.compute root() Logical Loop Structure: for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c()Resulting Code: for x: for y: tmp a = input[x, y] tmp b[y] = tmp a for y: output[x, y] = tmp b[y] 23 / 30 Naive Halide Representation Based on Halide scheduling language: a.compute at(b, y) b.compute at(c, x) c.compute root() ▶ 8 possible placements: ▶ compute at(a, x), ▶ compute at(a, y), ▶ compute at(b, x), ▶ compute at(b, y), ▶ compute at(c, x), ▶ compute at(c, y), ▶ compute root(), ▶ inline ▶ 3 computations that must be placed (a, b, c): ▶ 512 possible schedules 24 / 30 Naive Halide Representation Based on Halide scheduling language: a.compute at(b, y) b.compute at(c, x) c.compute root() ▶ 8 possible placements: ▶ compute at(a, x), ▶ compute at(a, y), ▶ compute at(b, x), ▶ compute at(b, y), ▶ compute at(c, x), ▶ compute at(c, y), ▶ compute root(), ▶ inline ▶ 3 computations that must be placed (a, b, c): ▶ 512 possible schedules 24 / 30 Naive Halide Representation Based on Halide scheduling language: a.compute at(b, y) b.compute at(c, x) c.compute root() ▶ 8 possible placements: ▶ compute at(a, x), ▶ compute at(a, y), ▶ compute at(b, x), ▶ compute at(b, y), ▶ compute at(c, x), ▶ compute at(c, y), ▶ compute root(), ▶ inline ▶ 3 computations that must be placed (a, b, c): ▶ 512 possible schedules 24 / 30 Naive Representation Does Not Work ▶ Naive representation works for simple halide programs ▶ Fails completely for more complex programs ▶ 474 of 512 schedules are invalid ▶ Callgraph orderings not respected ▶ Exponentially worse with larger programs ▶ Poor locality ▶ Small changes move large subtrees around 25 / 30 Naive Representation Does Not Work ▶ Naive representation works for simple halide programs ▶ Fails completely for more complex programs ▶ 474 of 512 schedules are invalid ▶ Callgraph orderings not respected ▶ Exponentially worse with larger programs ▶ Poor locality ▶ Small changes move large subtrees around 25 / 30 Better Representation for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() ▶ Representation based logical loop structure ▶ Loop structure can be reconstructed from token order ▶ Representation is a permutation of tokens that: ▶ Respects callgraph orderings ▶ Respects loop orderings ▶ Handling of some subtle corner cases and reorder() discussed in the paper 26 / 30 Better Representation for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() ▶ Representation based logical loop structure ▶ Loop structure can be reconstructed from token order ▶ Representation is a permutation of tokens that: ▶ Respects callgraph orderings ▶ Respects loop orderings ▶ Handling of some subtle corner cases and reorder() discussed in the paper 26 / 30 Better Representation for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() ▶ Representation based logical loop structure ▶ Loop structure can be reconstructed from token order ▶ Representation is a permutation of tokens that: ▶ Respects callgraph orderings ▶ Respects loop orderings ▶ Handling of some subtle corner cases and reorder() discussed in the paper 26 / 30 Better Representation for c x: for b x: for b y: for a x: for a y: compute a() compute b() for c y: compute c() ▶ Representation based logical loop structure ▶ Loop structure can be reconstructed from token order ▶ Representation is a permutation of tokens that: ▶ Respects callgraph orderings ▶ Respects loop orderings ▶ Handling of some subtle corner cases and reorder() discussed in the paper 26 / 30 Halide Blur 0 0.005 0.01 0.015 0.02 0.025 0.03 0 100 200 300 400 500 Execution Time (seconds) Autotuning Time (seconds) Hand-optimized OpenTuner 27 / 30 Halide Bilateral Grid 0 0.2 0.4 0.6 0.8 1 1.2 1.4 0 5000 10000 15000 Execution Time (seconds) Autotuning Time (seconds) Hand-optimized OpenTuner 28 / 30 Conclusions ▶ A lot of performance is left on the floor due to poorly optimized programs ▶ OpenTuner makes state of the art machine learning accessible to all ▶ Extensible configuration representation ▶ Ensembles of techniques ▶ Conventional wisdom underestimates the size tractable search spaces ▶ However, choosing the right representation is critical to successful autouners http://opentuner.org/ pip install opentuner Try OpenTuner today! 29 / 30 A Final Video 3 ▶ OpenTuner learning to play Super Mario Bros ▶ Every run that achieves a high score ▶ Runs that don’t make improvements are skipped ▶ Run # in top left caption ▶ Thanks! http://opentuner.org/ pip install opentuner Try OpenTuner today! 3http://youtu.be/O5IK9f2nBsE 30 / 30 Comparative Code Structure Analysis using Deep Learning for Performance Prediction Tarek Ramadan, Tanzima Z. Islam, Chase Phelps {t r297,tanzima,chaseleif}@txstate.edu Texas State University Nathan Pinnow, Jayaraman J. Thiagarajan {pinnow2,jayaramanthi1}@llnl.gov Lawrence Livermore National Laboratory Abstract—Performance analysis has always been an af- terthought during the application development process, focusing on application correctness first. The learning curve of the existing static and dynamic analysis tools are steep, which requires understanding low-level details to interpret the findings for actionable optimizations. Additionally, application performance is a function of a number of unknowns stemming from the application-, runtime-, and interactions between the OS and underlying hardware, making it difficult to model using any deep learning technique, especially without a large labeled dataset. In this paper, we address both of these problems by presenting a large corpus of a labeled dataset for the community and take a comparative analysis approach to mitigate all unknowns except their source code differences between different correct implementations of the same problem. We put the power of deep learning to the test for automatically extracting information from the hierarchical structure of abstract syntax trees to represent source code. This paper aims to assess the feasibility of using purely static information (e.g., abstract syntax tree or AST) of applications to predict performance change based on the change in code structure. This research will enable performance-aware application development since every version of the application will continue to contribute to the corpora, which will enhance the performance of the model. We evaluate several deep learning- based representation learning techniques for source code. Our results show that tree-based Long Short-Term Memory (LSTM) models can leverage source code’s hierarchical structure to dis- cover latent representations. Specifically, LSTM-based predictive models built using a single problem and a combination of multiple problems can correctly predict if a source code will perform better or worse up to 84% and 73% of the time, respectively. Index Terms—Comparative performance modeling, machine learning, Long Short-Term Memory Networks, Deep Graph Learning I. I NTRODUCTION The application development life cycle comprises a perpet- ual loop of design-development-testing. At least one-fourth of the life cycle for both scientific and commercial applications is spent in rigorous testing. However, performance modeling and analysis have mostly been an afterthought, with pro- gram correctness taking center. Most production environments assess program correctness through nightly regression tests to ensure building integrity in commercial and government research laboratories but do not consider performance. To combat the absence of performance prediction tools during code development, developers often spend a great deal of time in posterior dynamic (runtime) analysis by executing the target program and measuring the metrics of interest, e.g., time or hardware performance counters. Even though dynamic analysis is more thorough, this process costs hours for data collection and analysis time and requires a human in the loop. The cost of dynamic analysis motivates the need for static analysis based on information available before a code runs, such as code structure represented as an abstract syntax tree (AST). This work takes the first step toward developing such static analysis tools that can eventually predict the execution time of applications before running them by correlating code patterns to performance problems. While the need for performance regression tests and dynamic analysis will exist, this effort aims at reducing the time and effort spent by developers in dynamic analysis. The problem of predicting the absolute execution time of applications based on code structure alone is challenging since the execution time is a function of many factors, including the underlying architecture, the input parameters, and the application’s interactions with the OS. Hence, all work in the literature aiming to predict the absolute execution time based on static information (e.g., code structure) alone suf- fers from poor accuracy [20; 24]. In contrast, this paper circumvents that problem by taking a comparative approach to attribute changes in source code structure to performance f(δCode) →δPerformance and subsequently assess whether a new application will run faster or slower on the same system for similar input. In this context, we define model accuracy as the percentage of times the model (trained on an arbitrary dataset) correctly predicts the label (slower or otherwise) for a test code compared to another one, where the train and the test datasets are disjoint. E.g., DP-vs-DFS = 82% means that a model trained on data from several solutions to a Dynamic Programming (DP) problem can accurately predict the performance difference between a random pair of solutions to the Depth First Search (DFS) problem 82% of the time. Since we take a comparative approach, factors that impact applications outside of code structure get nullified. The three use cases of this research are—selecting the best algorithm to solve a problem out of several alternative solutions, predicting performance as a code evolves, and automatically generating semantically similar code suggestions with expected perfor- mance change. While the first two use cases can directly apply the source code embeddings generated in this research, the last one requires combining embeddings with code generation. To learn the correlation between δ(Code) and δ(Performance), we propose a novel static analysis approach that leverages a deep learning technique on Abstract Syntax Trees (AST). By directly operating on ASTs, we gain 1 arXiv:2102.07660v2 [cs.LG] 22 Apr 2021 Tag Contest Count Min (ms) Median (ms) Max (ms) StdDev Algorithms A 4 C 6616 86 1269 4063 445 Hashing [5] B 230 B 6099 31 658 1872 386 Binary search and number theory [6] C 1027 C 832 72 437 1455 344 Greedy [3] D 914 D 612 206 534 1965 464 Data structure and number theory [4] E 1004 C 505 3 80 137 48 Constructive algorithm F 1006 E 599 51 214 1647 471 DFS, Graphs, and Trees [2] G 1037 D 207 5 90 450 63 DFS, Graphs, and Trees [2] H 489 C 5192 2 9 29 15 Dynamic programming (DP) I 919 D 475 2 285 800 202 DFS, DP, Graphs TABLE I: Information about the selected problems. Run times are in milliseconds. The Contest column indicates a specific problem (e.g. C in 4 C) in a contest (e.g., 4 in 4 C) from Codeforces. The tags ( A-I) are only assigned for ease of reference. crucial structural information about code while dispensing variations in coding styles. To analyze the AST using deep learning, we build upon techniques initially designed for natural language processing, given the relevant nature between coding language and natural language. We propose to leverage tree-structured Long Short-Term Memory (LSTM) [34], which automatically learns to represent information inherent to a hierarchical data structure such as an AST to a vector form. In this effort, we also present a curated dataset comprising over 4M programs, annotated with execution times and mem- ory usage on the same system, from the online programming contest platform Codeforces [1]. We identified thousands of submissions that have significant variations in execution times to build a reliable model. Our work’s biggest strength is the models’ generalizability since they produce high-quality predictions ( 84% accurate on a single problem and 73% on multiple problems) for different algorithms solving different problems. While we do not anticipate entirely dispensing the need for performance analysts during optimizations, our methodology can reduce the amount of time, effort, and resources consumed in a posterior analysis by informing developers of cases where code changes introduce inefficiency. In summary, the contributions of this paper include: • An extensive labeled dataset of programs representing 1,278 different problems and 4,313,322 correct solutions to those problems with varying ranges of execution times. Such a dataset will be useful for further investigating generative deep learning techniques for automatic well-performing code generation. • Demonstrate the applicability of deep-learning for static code analysis to learn relationships between code structure changes and performance, assuming code versions run on the same machine. • An empirical study to make suitable recommendations for deep learning architecture design, training data sampling, and data augmentation to build predictive models. • A pipeline that can be integrated into the development phase of applications to improve prediction accuracy during production. • A discussion on the frontiers of generating well-performing code based on the work presented in this paper. II. D ATASET DESCRIPTION This section describes the data collection process, along with a brief discussion of the data characteristics. This dataset will be made publicly available via Github along with the pipeline presented in this paper. A. Data Collection We collected the dataset from an online platform, Code- forces [1], that organizes programming contests regularly. Each contest consists of a set of problems to which users submit their solutions. The online judge system automatically evaluates each solution for correctness using several test cases (typically 5 to 13, though the number varies among problems) and reports their corresponding runtime and memory usage. The dataset contains several unique solutions to each problem with varying runtime and memory usage characteristics, from which a deep learning model can “learn”. We develop a Python tool to automatically retrieve a list of contests from the Codeforces website using their provided API and disregard any contest that has not yet finished. Subsequently, our data collection tool carries out an API request for a list of submission IDs for each contest in the retrieved list. For each problem, our tool parses all submissions ignoring those marked by Codeforces as incorrect solutions. Finally, our tool enters each problem set along with source code, source language, runtime, and memory usage properties to a database for each test case. This process results in a total of 4,313,322 correct solu- tions, spanning across 1,278 problems. The distribution of so- lution times ranges from 6 problems, each having over 40,000 submissions to 600 problems, each having less than 1,000 submissions. Each problem is unique in regards to its difficulty and popularity. For training, it is crucial to select problem sets that have a sufficient number of solutions and are of sufficient difficulty such that runtime and memory usage across solutions show non-trivial variability. In this paper, we only focus on submissions written in C++, and the tests are averaged to obtain a mean runtime for each problem. However, the tool is generic in its ability to collect all programs written in all languages. We present the performance of the built models in Section VI from seven groups of algorithms. Table I presents statistics and descriptions of these nine selected problems 2 ROSE Prediction c1 c2 AST2 AST1 Neural Network Node Rep. Code Rep. Input Processing Deep Representation Learning Predictive ModelSource code Node Rep. Code Rep. Fig. 1: An overview of the proposed deep-learning methodology. Deep representation learning model builds code representation that the predictive model uses to predict if the second code is expected to be more efficient (in terms of execution time). (Tags A-I). These problems are automatically selected based on sufficient variation in execution times and more than 100 correct solutions. While not all of the algorithms in our dataset represent scientific applications, Dynamic Programming (DP) and Graph Traversal are two of the 13 dwarfs of scientific applications, and shortest path algorithms are core to several commercial ones. B. Generating Code Pairs As described in the previous section, we formulate the problem of comparative performance analysis as correlating δ(Code) for a pair of source codes with δ(performance). This formulation takes a differential approach instead of predicting the absolute performance of a new or a variant of the same application, which can be intractable given that execution time is a factor of a large number of variables. Our pipeline automatically generates pairs of codes from the selected problems for training a robust model to facilitate this formulation. Since the ordering of every set of codes could be considered as a unique pair, for N submissions, there exists a total of N2 possible pairs. Though data-driven approaches such as deep neural networks are typically known to require large amounts of data, we argue that all possible pairs are not required to train a robust model. Not all pairs add unique information for the model to learn, and repetitive training creates a model that has been overfitted. Hence, in Section VI-D, we evaluate the data requirements to build a robust model. The state-of-practice method for reducing the training dataset is to use random subsets of input. Hence, we explore the use of random subsets (of code pairs) of varying sizes for training the models and make appropriate recommendations. For every pair of programs, we generate the target variable (binary) as follows: if the first element of the pair has a higher execution time, we label it as positive, otherwise negative. This formulation emulates a developer looking to determine if a new version of the program will have a lower (improved) runtime. Our experiments also study the impact of including two-way ordering of every pair of codes, i.e., (a,b) and (b,a) on the model accuracy. III. P ROPOSED APPROACH Figure 1 shows an overview of our approach that con- verts each source code to an AST by using the ROSE [30] compiler and subsequently utilizes a deep neural network to learn embeddings from ASTs that incorporate structural information automatically. Embedding learning is an active area of research with several algorithms such as deep graph convolutional network [31], deep graph attention network [36], and LSTM [33]. An adequate representation improves the accuracy of the downstream analysis tasks (e.g., performance prediction in our case) by capturing discriminatory information that contributes to determining a label. These embeddings then become the input to a classifier module that implements a fully connected neural network to perform the prediction. While this paper mainly focuses on ASTs to build a deep learning pipeline for static program modeling, we expect that information gathered during compile-time, such as control and data flow graphs, may improve a model’s accuracy. A. Problem Formulation: Formally, let us denote the ASTs for a pair of source code by pi and pj respectively, where every pi ∈P is a submission pertinent to the problem P. We define a deep feature extractor F that processes an AST to produce a latent representation z∈Z, where Z denotes the latent space. Mathematically, this process is expressed as F : P ↦→ Z. Since the goal is to predict if the AST of pj is expected to have a lower execution time than pi, we first concatenate their features to produce ¯zij = [zi,zj]. As a result, when the dimensionality of the latent space Z is d, the size of the concatenated feature ¯zij becomes 2 ∗d. The classifier function C maps the concatenated feature ¯zij ∈ ¯Z into the target variable yij ∈Y, where the output space Y is discrete and assumes one of the two values 0 or 1. In other words, the classifier mapping can be expressed as C : ¯Z ↦→Y. The feature extractor F consists of two components. First, it learns to represent each code construct of an AST ( node of a tree) using an embedding lookup function that assigns a feature vector to each node depending on its type (e.g., for loops or if statements). Second, it learns representation for the entire AST or a sub-tree using the deep learning algorithm ( z). In this paper, we propose tree-LSTM for automatic feature representation. Section III-B discusses our rationale in details. Our proposed approach jointly infers the representations for each of the nodes and subsequently for the entire AST. This automated learning approach alleviates the need for any man- ual feature engineering technique, which presents a nontrivial 3 Fig. 2: Proposed training strategies based on tree-structured LSTMs for processing ASTs. Arrows going from root to leaves (and vice versa) indicate information flow in the LSTM, arrows between trees indicate information flow between layers. challenge for source code. The classifier is implemented as a feed-forward network and produces the likelihood of one version of the code being superior to the other in terms of expected performance. This likelihood is then encoded into a decision label using Equation ??: pred(pi,pj) → { 0 ti