之前的文章中講到了,mlir可以通過兩種方法將產生的表示式進行變型,即直接使用c++編寫表示式的匹配與重寫函式和使用drr規則來定義重寫規則。通過上述兩種方法,可以將產生的表示式進行自定義的變型,比如去掉冗餘transpose
操作等等。但是,這樣的方法只能針對特定的乙個operation進行變型,在遇到相似的變型時,無法重用之前的變型方法。因此本文將會介紹泛化的表示式變型。
def multiply_transpose(a, b)
def main()
例子中使用toy語言定義了multiply_transpose
方法,也就是將兩個張量進行轉置,再進行對應元素相乘(注意:這裡的*
運算子表示對應元素相乘)。
對於這樣的例子,當我們不進行任何優化生成mlir表示式的時候,除了在例項化tensor的時候,其他時候並不能知道tensor的shape資訊。如下圖所示,使用的是泛化的tensor型別。
使用內聯pass,可以用定義的函式體替代函式的呼叫。對於multiply_transpose
這種函式,函式的呼叫、返回有關的準備和收尾工作的**往往比函式體本身的**要大得多。因此,對於這類簡單的、使用頻繁的小函式,將之宣告為內聯函式可提高執行效率。那麼在上述示例中,應該如何實現內聯的pass呢?
首先,我們要實現內聯pass的表示式變型規則,這裡就要提到了dialect介面,mlir提供了dialectinlinerinte***ce
介面,也就是說mlir本身提供了處理內聯的介面。這樣一來,我們只需要繼承dialectinlinerinte***ce
,然後再實現所需函式,就可以自定義內聯的操作,制定表示式變型規則。
除此之外,內聯的過程還需要知道在**進行內聯,這就要求知道在main函式中呼叫multiply_transpose
的位置。這裡我們將要提到的是operation介面,mlir中提供了乙個callopinte***ce
介面, 將會對函式呼叫進行標記,以此告知內聯操作函式呼叫的位置。operation介面的粒度比dialect介面的小,也就是說dialect介面的作用範圍是整個dialect,operation介面就是針對特定operation進行操作。
在確定了內聯操作的表示式變型規則以及定位到函式呼叫位置之後,下面解決的問題就是,函式定義時的型別和函式呼叫時的型別不一致,也就是說當函式定義時的引數使用的是泛化的tensor型別,但是函式呼叫時的引數是確定型別的tensor,在內聯操作時需要對其型別進行統一。為了解決這樣的問題,我們需要增加乙個castop,用來將變數確定的型別轉變為泛化的型別。在operation模組中定義castop,再在dialect模組的內聯操作介面中,重寫相應函式,從而實現在mlir表示式中加入castop,將確定的型別轉化為泛化的型別。這樣一來,在函式呼叫處,內聯操作就可以將函式定義,嵌入到函式呼叫位置。
到此為止,我們實現了內聯操作,現在的mlir表示式已經沒有了函式定義的表示式,全部嵌入了main函式中。
我們通過castop實現了將確定型別的tensor轉變成了泛化型別的tensor ,才使內聯操作得以完成。下一步要解決的就是,根據那些確定型別tensor,將那些泛化的tensor都轉變為確定型別的tensor,這裡我們將要用ods框架來生成自定義的operation介面,這個介面就是用來推測tensor的shape型別。整個shape推斷也將會編寫為乙個pass作用在mlir表示式上。
首先,使用ods框架的規則編寫shape推斷的介面模組。由於這是operation介面,所以是作用在特定的operation上的,因此下一步就是要指定哪些operation將會使用shape推斷介面。除此之外,還要為各個使用shape推斷介面的operation,實現介面中的infershapes
函式。最後定義乙個shape推斷介面的類,提供shape推斷演算法,並建立乙個pass,在passmanger中進行新增。
其中,shape推斷的演算法如下圖所示:
到此為止,我們實現了內聯操作,並且成功推測了各個泛化tensor的shape資訊。我們使用了dialect介面使用了泛化的內聯操作介面,並進行自定義操作;使用了mlir提供的operation介面定位函式呼叫位置;使用了ods框架定義operation介面,進行shape推斷。再配合其他的幾個規範化的pass,得到了最終變型後的mlir表示式的結果。
借助這個例子也說明了使用泛化的重用表示式變型的操作,同時也說明了mlir可重用性與可擴充套件性。
字尾表示式實現表示式求值
看到別人寫的乙個表示式求值程式,想到很久之前寫的乙個。中間有個字串轉數值型,可以用stringstream來實現或者c語言裡面的strtod直接得到 include include include include includeusing namespace std class data doubl...
表示式求值的實現
表示式求值是乙個很有意思的技術話題,國內外討論這個話題的技術人員很多,也有非常多的實現方案。倒不是說這個問題很難解決,只是說它提供了很好的話題,讓各路高手使用自己的手段來解決問題,百家爭鳴,各展所長。該話題也提供了乙個非常好的想像空間讓大家一起討論技術討論方案,也是乙個資料結構教程中的經典教育案例。...
java實現中綴表示式轉字尾表示式
public class stacktest 等級很重要 優先順序最高的是 因為一定會進棧 次之為 再為 優先順序最低的是 一定會連帶其他的運算子出棧 數字不進棧 param c return public static int level char c else if indexof c 1 el...