Pass Infrastructure基础架构(上)

Operation
Pass

OperationPass
Op-Specific
OperationPass
Op-Agnostic
Dependent
Dialects

Analysis
Management

Querying
Analyses
Preserving
Analyses

Pass
Failure
Pass
Manager

OpPassManager

Dynamic
Pass Pipelines
Instance
Specific Pass Options
Pass
Statistics
Pass
Registration

Pass
Pipeline Registration
Textual
Pass Pipeline Specification

Declarative
Pass Specification

Tablegen
Specification

Pass
Instrumentation

Standard
Instrumentations

Crash and
Failure Reproduction

Local
Reproducer Generation

pass代表了转换和优化的基本基础架构。本文档概述了MLIR中的pass基础结构以及如何使用它。

有关MLIR 及其核心方面(如IR结构和算子)的更多信息,请参见 MLIR规范。

有关 在MLIR中进行图形重写的快速入门,请参见 MLIR Rewrites。如果转换涉及模式匹配算子DAG,那么这是一个很好的起点。

算子pass

在MLIR中,抽象和转换的主要单元是一个 运算 。这样,pass管理器被设计为处理不同嵌套级别的算子实例。pass通行管理器的结构 和嵌套的概念将在下面详细介绍。MLIR中的所有pass均源自OperationPass,并遵守以下限制;在多线程和其它高级方案中,任何不符合都会导致有问题的行为:

修改正在算子的当前之外引用或依赖的任何状态。这包括在父块中添加或删除算子,更改属性(取决于当前算子的规定)/当前算子数/结果/后继对象。
修改另一个未嵌套在当前算子的状态。

其它线程可能同时在这些算子上运行。

检查同级算子的状态。

其它线程可能正在并行修改这些算子。
允许检查祖先/父项算子的状态。

步长调用pass状态runOnOperation保持可变的。传递可能在许多不同的算子上运行,而不能保证执行顺序。

在进行多线程处理时,特定的传递实例甚至可能不会在IR内的所有算子上执行。因此,传递不应该依赖于所有算子上的运行。

保持任何全局可变状态,例如源文件中的静态变量。所有可变状态都应pass传递实例来维护。
必须是可复制的

流程管理器可以创建流程的多个实例,以并行处理算子。

创建算子传递时,根据使用情况,有两种不同的类型可供选择:

OperationPass:特定于算子

在op-specific算子上传递给定算子类型明确的算子。此算子类型必须遵守pass管理器设置的限制,以执行pass。

要定义特定于算子通道,派生类必须遵守以下规定:

从CRTP类继承,OperationPass并提供算子类型作为附加模板参数。
覆盖void
runOnOperation()虚拟方法。

一个简单的过程可能看起来像:

namespace {

/// Here
we utilize the CRTP PassWrapper utility class to provide some

///
necessary utility hooks. This is only necessary for passes defined directly

/// in
C++. Passes defined declaratively use a cleaner mechanism for providing

/// these
utilities.

struct MyFunctionPass : public PassWrapper<OperationPass,

MyFunctionPass> {

void runOnOperation() override {

// Get the
current FuncOp operation being operated on.

FuncOp f =
getOperation();

// Walk
the operations within the function.

f.walk([](Operation *inst) {

});

}

};

} // end anonymous namespace

///
Register this pass so that it can be built via from a textual pass pipeline.

/// (Pass
registration is discussed more below)

void registerMyPass() {

PassRegistration(

“flag-name-to-invoke-pass-via-mlir-opt”, “Pass
description here”);

}

OperationPass:不可知

op-agnostic pass,添加到通管理器的算子类型进行运算。这意味着这种类型的pass通道可以在几种不同的算子类型上进行运算。通常使用算子接口 和 特征来存储此类pass 。此类pass传递的示例包括“ 常见子表达式消除” 和“ 内联” 。

要创建算子pass传递,派生类必须遵守以下规定:

从CRTP类继承OperationPass。
覆盖虚拟void
runOnOperation()方法。

一个简单的过程可能看起来像:

/// Here
we utilize the CRTP PassWrapper utility class to provide some

///
necessary utility hooks. This is only necessary for passes defined directly

/// in
C++. Passes defined declaratively use a cleaner mechanism for providing

/// these
utilities.

struct MyOperationPass : public PassWrapper<OperationPass<>, MyOperationPass> {

void runOnOperation() override {

// Get the
current operation being operated on.

Operation *op =
getOperation();

}

};

从属语言

必须先在MLIRContext中加载语言,然后才能从这些语言创建实体(算子,类型,属性等)。在开始执行多线程传递管道之前,还必须加载语言。为此,可能无法保证已从其加载的语言创建实体的过程,必须pass重写getDependentDialects() 方法并明确声明此语言列表来表达。

分析管理

一个重要的概念,以及转换过程,都是分析。这些在概念上与转换过程相似,不同之处在于不修改特定算子的情况下计算信息。在MLIR中,分析不是pass而是pass独立式类,这些类是按需延迟计算并缓存的,以避免不必要的重新计算。MLIR中的分析必须遵循以下条件:

提供一个采用Operation*的有效构造函数。
不得修改给定的算子。

分析可能会提供其它钩子来控制各种行为:

bool isInvalidated(const
AnalysisManager::PreservedAnalyses &)

给定一个保留的分析集,如果该分析确实无效,则该分析返回true。如果没有明确标记保留分析,但可以根据其它属性(例如分析集)保留(或使之无效),则可以进行更精细的失效。

查询分析

基OperationPass类提供用于查询和保留当前正在处理的算子的分析的实用程序。

OperationPass自动提供以下实用程序来查询分析:

getAnalysis<>

获得当前算子的分析,并在必要时进行构建。

getCachedAnalysis<>

获取当前算子的分析(如果已经存在)。

getCachedParentAnalysis<>

获取给定父算子的分析(如果存在)。

getCachedChildAnalysis<>

对给定的子算子(如果存在)进行分析。

getChildAnalysis<>

对给定的子算子进行分析,并在必要时进行构造。

使用上面定义的示例pass传递,看一些示例:

/// An
interesting analysis.

struct MyOperationAnalysis {

// Compute
this analysis with the provided operation.

MyOperationAnalysis(Operation *op);

};

void MyOperationPass::runOnOperation()
{

// Query
MyOperationAnalysis for the current operation.

MyOperationAnalysis &myAnalysis =
getAnalysis();

// Query a
cached instance of MyOperationAnalysis for the current operation.

// It will
not be computed if it doesn’t exist.

auto optionalAnalysis =
getCachedAnalysis();

if (optionalAnalysis)

// Query a
cached instance of MyOperationAnalysis for the parent operation of

// the
current operation. It will not be computed if it doesn’t exist.

auto optionalAnalysis =
getCachedParentAnalysis();

if (optionalAnalysis)

}

保存分析

在pass查询后构造的分析将被缓存,以避免不必要的计算(如果稍后再次请求)。为避免过时的分析,假定所有分析均pass传递而无效。为避免无效,过程必须专门标记已知保留的分析。

所有Pass类都会自动提供以下用于保留分析的实用程序:

markAllAnalysesPreserved
markAnalysesPreserved<>

void MyOperationPass::runOnOperation()
{

// Mark
all analyses as preserved. This is useful if a pass can guarantee

// that no
transformation was performed.

markAllAnalysesPreserved();

// Mark
specific analyses as preserved. This is used if some transformation

// was
performed, but some analyses were either unaffected or explicitly

//
preserved.

markAnalysesPreserved<MyAnalysis,
MyAnalyses…>();

}

pass失败

允许MLIR中的传递正常失败。如果pass的某些不变性被破坏,可能会使IR处于某种无效状态,则可能发生这种情况。如果发生这种情况,signalPassFailure方法直接向pass管理器发出故障信号。如果pass指示执行时失败,则管道中不会执行其它任何传递,并且顶级调用PassManager::run将返回failure。

void MyOperationPass::runOnOperation()
{

// Signal
failure on a broken invariant.

if (some_broken_invariant)

return signalPassFailure();

}

pass管理器

以上各节介绍了pass的不同类型及其不变性。本节介绍PassManager的概念,以及如何将其用于配置和计划pass管道。与pass管理相关的主要类别有两个,PassManager和和OpPassManager。 PassManager类作为顶层的入口点,并包含用于整个管道的各种配置。OpPassManager用于调度类会将以嵌套的一个特定的水平上运行。顶级 PassManager还用作OpPassManager。

OpPassManager

AnOpPassManager本质上是要在特定类型的算子上执行的过程的集合。此算子类型必须符合以下要求:

必须注册并标记 IsolatedFromAbove 。

预期传递不会修改正在处理的当前算子或更高的算子。如果算子不是孤立的,则可能会无意间修改或遍历不应该执行的算子的SSA使用列表。

将pass添加到pass管理器addPass。该pass必须是采用 op-specific与相同算子类型OpPassManager的op-agnosticpass,或者是pass。

一个OpPassManager通常被cretedOpPassManagerpassnest<>方法明确嵌套内其它现有管道。此方法采用嵌套通行管理器将要算子的算子类型。在顶层,a PassManager充当OpPassManager。从这个意义上讲,嵌套对应 于 IR区域内的 结构嵌套 。

例如,以下content.mlir:

module {

spv.module “Logical”
“GLSL450” {

func @foo() {

}

}

}

具有以下嵌套结构:

module

spv.module

function

下面是构造在上述结构上运行的管道的示例:

// Create
a top-level PassManager class. If an operation type is not

//
explicitly specific, the default is the builtin module operation.

PassManager
pm(ctx);

// Note:
We could also create the above PassManager this way.

PassManager
pm(ctx, /operationName=/“module”);

// Add a
pass on the top-level module operation.

pm.addPass(std::make_unique());

// Nest a
pass manager that operates on spirv.module operations nested

//
directly under the top-level module.

OpPassManager
&nestedModulePM = pm.nestspirv::ModuleOp();

nestedModulePM.addPass(std::make_unique());

// Nest a
pass manager that operates on functions within the nested SPIRV

// module.

OpPassManager
&nestedFunctionPM =
nestedModulePM.nest();

nestedFunctionPM.addPass(std::make_unique());

// Run the
pass manager on the top-level module.

ModuleOp m
= …;

if (failed(pm.run(m)))

… // One of the passes signaled a failure.

上面的过程管理器包含以下管道结构:

OpPassManager

MyModulePass

OpPassManagerspirv::ModuleOp

MySPIRVModulePass

OpPassManager

MyFunctionPass

然后,这些管道一次运行一次。这意味着,例如,给定FuncOp上的一系列连续传递,它将在第一个函数上全部执行,然后在第二个函数上全部执行,依此类推,直到整个程序都pass传递为止。这提供了几个好处:

这改善了编译器的缓存行为,因为它一次只连接一个功能函数,而不遍历整个程序。
pass减少需要调度的作业数量以及提高每个作业的效率,这提高了多线程性能。整个函数管道可以在每个函数上异步运行。

动态pass管道

在某些情况下,在另一个遍历中运行一个遍历管道可能是有用的,以允许基于正在运行的当前算子的某些不变性进行配置或过滤。例如, Inliner Pass 可能希望在进行内联时,运行过程内pass简化,以产生更好的成本模型,并提供更好的内联。为了实现这一点,pass过程可以OpPassManagerpassLogicalResult Pass::runPipeline(OpPassManager &,
Operation *)方法对正在执行的当前算子或嵌套在当前算子内的任何算子进行任意运算。与顶级PassManager::run方法的结果类似,此方法返回动态管道是成功还是失败。下面是一个简单的示例:

void MyModulePass::runOnOperation()
{

ModuleOp module =
getOperation();

if (hasSomeSpecificProperty(module)) {

OpPassManager dynamicPM(“module”);

…; // Build the dynamic pipeline.

if (failed(runPipeline(dynamicPM, module)))

return signalPassFailure();

}

}

注意:尽管上面在runOnOperation方法中构造了动态管道 ,但这不是必需的,并且应尽可能缓存管道,因为OpPassManager可以安全地复制该类。

每当pass管道以嵌套方式运行时,即当无法与主传递管道的其余部分一起静态调度嵌套管道时,都应使用本节中描述的机制。更具体地说,PassManager通常不应在内构造a Pass。使用runPipeline还可以确保将所有分析, 设备 和其它与过程管理器相关的组件与正在执行的动态管道集成在一起。

实例特定的pass选项

MLIR提供了一种内置的机制,用于指定配置其行为的选项。这些选项在遍历构造时针对遍历的每个实例独立地进行解析。使用Option<>和 ListOption<>类定义选项,并遵循 LLVM命令行 标志定义规则。参见以下示例:

struct MyPass … {

/// Make
sure that we have a valid default constructor and copy constructor to

/// ensure
that the options are initialized properly.

MyPass() = default;

MyPass(const MyPass& pass) {}

/// Any
parameters after the description are forwarded to llvm:

Pass Infrastructure基础架构(上)相关推荐

  1. Pass Infrastructure基础架构(下)

    Pass Infrastructure基础架构(下) pass注册 PassRegistration该类在示例中简要显示了各种pass类型的定义 .该机制允许注册pass类,以便可以在文本pass管道 ...

  2. 初创企业股权架构_初创企业如何以每月不到200美元的价格利用生产级基础架构...

    初创企业股权架构 Before you can launch a new service, you need infrastructure. You want reliability, scalabi ...

  3. 软件架构万字漫谈:业务架构、应用架构与云基础架构

    软件架构万字漫谈:业务架构.应用架构与云基础架构 本部分节选自<软件架构设计> 软件开发就是把一个复杂的问题分解为一系列简单的问题,再把一系列简单的解决方案组合成一个复杂的解决方案.而软件 ...

  4. 微软推超融合基础架构解决方案 企业可在本地端做虚拟化应用

    微软在其混合云平台Azure Stack上,推出超融合基础架构解决方案Azure Stack HCI(Hyperconverged Infrastructure),企业现在可以在本地端(On-prem ...

  5. 云计算的基础架构:并行计算+资源虚拟化

    云计算的基础架构:并行计算+资源虚拟化 (2011-08-20 12:15:51) 标签: 校园 分类: 工作篇 高性能云计算:从科学应用的角度 科学计算往往需要可用的数量庞大的计算机来执行大规模实验 ...

  6. 云计算服务模型,第 1 部分: 基础架构即服务(IaaS)

    英文原文:Cloud computing service models, Part 1: Infrastructure as a Service 本文介绍三个云类别中的第一个:基础架构即服务(infr ...

  7. 数据中心基础架构 22 年演进

    01 前言 当今世界正处在信息技术(IT)创新的黄金时代.由机器学习.物联网和大规模可扩展应用支持的云计算.移动应用.大数据分析的巨大力量正在重塑商业和社会的方方面面.而这场IT复兴的中心,则是超大规 ...

  8. 助力企业应用与基础架构现代化 VMware这波组合拳够强!

    顺应时代的发展,"数字化转型"已经成为企业发展的必由之路.应用作为数字化转型的核心,能够帮助企业向客户提供定制化的数字化体验,创造新的收入来源.在数字化转型道路上,中国企业走的并不 ...

  9. 云中台技术架构_为什么开放基础架构在云中很重要

    云中台技术架构 在阅读红帽首席执行官Jim Whitehurst的最新文章时,我对OpenStack与州际公路系统之间的比较感到震惊. < 华尔街与科技>上的文章名为" Open ...

最新文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(50)-Easyui 扁平化皮肤
  2. 参数整定临界比例度实验_实验低温浴“秘方”,调节两个溶剂的比例实现零下10度到78度定温配制...
  3. C#为什么会这么慢之命运之终章-真理篇for firelong
  4. ORACLE RAC如何增加节点
  5. 一夜身价暴涨千倍,程序员如何发布自己的 ICO?
  6. Android支付宝刷步数,支付宝运动怎么刷步数? 支付宝如何快速刷步数?
  7. 【君思智慧园区】智慧能源综合管理平台,智慧能源管理云平台建设方案!
  8. 集成电路制造工艺及设备
  9. 80后一代开始结婚 独生子女开始承担新的责任
  10. python3d动画效果_使用Matplotlib 3D实现三维波浪动画
  11. 三星手机终于更新系统了,我的是s22u
  12. 怎么写好一篇接口文档
  13. iOS_核心动画(二)
  14. 中国富豪的七条发家路--颇显中国特色
  15. nginx启动无反应
  16. 安信可 ESP8266 12F Flash操作
  17. Visio安装问题解决:office即点即用安装程序
  18. solr6 mysql_solr6.6.0学习(2)创建核心和与Mysql数据库连接
  19. Apache Camel核心概念
  20. 如何判断一个数是不是素数?

热门文章

  1. Golang TDD实践报告:快速排序Quick Sort
  2. Oracle type (自定义类型的使用)
  3. 固定table标题头、标题列(兼容多种浏览器)
  4. 2019秋招面试常考题目
  5. dataframe多列合并成一列
  6. kwargs.pop是什么意思
  7. SpringSecurity安全验证中文乱码问题
  8. 深度学习编译器综述The Deep Learning Compiler
  9. Camera系列规格参数
  10. 传统编译器与神经网络编译器