当前位置: 首页 > news >正文

网站同步到新浪微博上海公司网站建设公司

网站同步到新浪微博,上海公司网站建设公司,建设网站的视频,网页界面设计的起源5. 方言与操作 5.1. 方言的概念 在MLIR里#xff0c;通过Dialect类来抽象方言。具体的每种方言都需要从这个基类派生一个类型#xff0c;并实现重载自己所需的虚函数。 MLIR文档里这样描述方言#xff08; MLIR Language Reference - MLIR#xff09;#xff1a; 方言…5. 方言与操作 5.1. 方言的概念 在MLIR里通过Dialect类来抽象方言。具体的每种方言都需要从这个基类派生一个类型并实现重载自己所需的虚函数。  MLIR文档里这样描述方言 MLIR Language Reference - MLIR 方言是这样的机制它融入并扩展MLIR生态系统。它们允许定义新的操作以及属性与类型。向每个方言给出唯一的名字空间作为定义的每个属性/操作/类型的前缀。例如Affine方言定义了名字空间affine。 MLIR允许多个方言共存于一个模块中即使是在主干之外的那些。方言由特定的遍生成与消费。对不同的方言之间以及方言内部的转换MLIR提供了一个框架。MLIR支持的几个方言 Affine dialectGPU dialectLLVM dialectSPIR-V dialectStandard dialectVector dialect 在教程中还给出了Toy方言的例子。 5.2. 操作的概念 MLIR引入了一个称为操作operation的统一概念来描述许多不同的抽象与计算层次。在MLIR系统中从指令到函数再到模块一切都塑造为Op。 MLIR没有固定的Op集合因此允许并鼓励用户自定义扩展Op。编译器遍会保守地对待未知Op并且MLIR支持通过特征traits、特权操作hook和优化接口等方式向遍描述Op语义。MLIR里的操作是完全可扩展的没有固定的操作列表并具有应用特定的语义。例如MLIR支持目标无关操作、仿射affine操作以及目标特定机器操作。 操作的内部表示是简单的操作由一个唯一字符串标识如dim、tf.Conv2d、x86.repmovsb、ppc.eieio等可以返回0或多个结果接受0或多个操作数有一个属性字典有0或多个后继者以及0或多个封闭的区域。通用打印形式包括所有这些元素加上一个函数类型来表示结果与操作数的类型。 例子 // An operation that produces two results. // The results of %result can be accessed via the name # opNo syntax. %result:2 foo_div() : () - (f32, i32) // Pretty form that defines a unique name for each result. %foo, %bar foo_div() : () - (f32, i32) // Invoke a TensorFlow function called tf.scramble with two inputs // and an attribute fruit. %2 tf.scramble(%result#0, %bar) {fruit banana} : (f32, i32) - f32 5.3. 方言的管理 显然管理方言最恰当的地方就是MLIRContext不过MLIRContext只是上下文的接口真正的实现是MLIRContextImpl。在MLIRContextImpl中有这样一些容器 DenseMapStringRef, std::unique_ptrDialect loadedDialects DialectRegistry dialectsRegistry llvm::StringMapAbstractOperation registeredOperations llvm::StringMapPointerUnionDialect *, MLIRContext *, llvm::BumpPtrAllocator identifiers 第一个容器保存已载入的方言对象第二个容器记录已注册的方言第三个容器保存已注册的抽象操作第四个容器记录上下文里可见的标识符。 这里方言的注册是指MLIRContext知道这个方言的标识符和构造方法但方言对象并没有构造。方言对象的构造发生在载入时在载入时刻不仅构造方言对象相关的接口也会一并准备好。抽象操作与操作相关参考操作的管理。 5.3.1. 方言的注册 MLIR提供了一组标准的方言它们提供了许多有用的功能。为了让程序能方便地使用标准方言首先每个程序在main()的入口都要注册标准方言像这样 int main(int argc, char **argv) { mlir::registerAllDialects(); …      // 其他初始化 registerAllDialects()的定义如下 67  inline void registerAllDialects() { 68    static bool initOnce 69        ([]() { registerAllDialects(getGlobalDialectRegistry()); }(), true); 70    (void)initOnce; 71  } 69行的getGlobalDialectRegistry()返回一个类型为llvm::ManagedStaticDialectRegistry的对象dialectRegistry它过可视为DialectRegistry的静态对象这个类通过一个类型为std::mapstd::string, std::pairTypeID, DialectAllocatorFunction的容器registry来记录标准方言。因此同一行上的registerAllDialects()重载函数是 41  inline void registerAllDialects(DialectRegistry registry) { 42    // clang-format off 43    registry.insertacc::OpenACCDialect, 44                    AffineDialect, 45                    avx512::AVX512Dialect, 46                    gpu::GPUDialect, 47                    LLVM::LLVMAVX512Dialect, 48                    LLVM::LLVMDialect, 49                    linalg::LinalgDialect, 50                    scf::SCFDialect, 51                    omp::OpenMPDialect, 52                    pdl::PDLDialect, 53                    pdl_interp::PDLInterpDialect, 54                    quant::QuantizationDialect, 55                    spirv::SPIRVDialect, 56                    StandardOpsDialect, 57                    vector::VectorDialect, 58                    NVVM::NVVMDialect, 59                    ROCDL::ROCDLDialect, 60                    SDBMDialect, 61                    shape::ShapeDialect(); 62    // clang-format on 63  } 这个方法列出了MLIR目前实现的标准方言DialectRegistry通过一系列insert()方法完成注册 252    template typename ConcreteDialect, typename OtherDialect, 253                typename... MoreDialects 254      void insert() { 255        insertConcreteDialect(); 256        insertOtherDialect, MoreDialects...(); 257      } 241    template typename ConcreteDialect 242    void insert() { 243      insert(TypeID::getConcreteDialect(), 244             ConcreteDialect::getDialectNamespace(), 245             static_castDialectAllocatorFunction(([](MLIRContext *ctx) { 246               // Just allocate the dialect, the context 247               // takes ownership of it. 248               return ctx-getOrLoadDialectConcreteDialect(); 249             }))); 250    } 53  void DialectRegistry::insert(TypeID typeID, StringRef name, 54                               DialectAllocatorFunction ctor) { 55    auto inserted registry.insert( 56        std::make_pair(std::string(name), std::make_pair(typeID, ctor))); 57    if (!inserted.second inserted.first-second.first ! typeID) { 58      llvm::report_fatal_error( 59          Trying to register different dialects for the same namespace: 60          name); 61    } 62  } 注意这里只是注册了这些方言的构造方法并没有把这些方言的Dialect对象构造出来。这是因为Dialect对象的构造需要一个MLIRContext实例因此要把Dialect对象的构造推迟到MLIRContext对象构造出来后。另外不是每个程序都需要所有的标准方言在需要时构造所需的方言才比较合理。所以DialectRegistry提供了两个函数loadByName()loadAll()。前者构造指定名字的标准方言后者构造所有的标准方言。 5.3.2. 方言的载入 从上面注册的构造方法我们看到实际执行构造的函数是MLIRContext的getOrLoadDialect()这也是一系列调用 69    template typename T 70      T *getOrLoadDialect() { 71        return static_castT *( 72          getOrLoadDialect(T::getDialectNamespace(), TypeID::getT(), [this]() { 73            std::unique_ptrT dialect(new T(this)); 74            return dialect; 75          })); 76    } 模板参数T是具体的方言类型它是Dialect的派生类Dialect没有定义getDialectNamespace()派生类必须提供自己的定义。在MLIRContext里这个名字将作为这个方言的身份识别。另外Dialect及其派生类亦是MLIR类型系统中的组成它们都有TypeIDMLIRContext::getOrLoadDialect()在2021版本里的定义如下 511  Dialect * 512  MLIRContext::getOrLoadDialect(StringRef dialectNamespace, TypeID dialectID, 513                                function_refstd::unique_ptrDialect() ctor) { 514    auto impl getImpl(); 515    // Get the correct insertion position sorted by namespace. 516    std::unique_ptrDialect dialect impl.loadedDialects[dialectNamespace]; 517   518    if (!dialect) { 519      LLVM_DEBUG(llvm::dbgs() 520                  Load new dialect in Context dialectNamespace \n); 521  #ifndef NDEBUG 522      if (impl.multiThreadedExecutionContext ! 0) 523        llvm::report_fatal_error( 524            Loading a dialect ( dialectNamespace 525            ) while in a multi-threaded execution context (maybe 526            the PassManager): this can indicate a 527            missing dependentDialects in a pass for example.); 528  #endif 529      dialect ctor(); 530      assert(dialect dialect ctor failed); 531   532      // Refresh all the identifiers dialect field, this catches cases where a 533      // dialect may be loaded after identifier prefixed with this dialect name 534      // were already created. 535      llvm::SmallString32 dialectPrefix(dialectNamespace); 536      dialectPrefix.push_back(.); 537      for (auto identifierEntry : impl.identifiers) 538        if (identifierEntry.second.isMLIRContext *() 539            identifierEntry.first().startswith(dialectPrefix)) 540          identifierEntry.second dialect.get(); 541   542      // Actually register the interfaces with delayed registration. 543      impl.dialectsRegistry.registerDelayedInterfaces(dialect.get()); 544      return dialect.get(); 545    } 546   547    // Abort if dialect with namespace has already been registered. 548    if (dialect-getTypeID() ! dialectID) 549      llvm::report_fatal_error(a dialect with namespace dialectNamespace 550                                has already been registered); 551   552    return dialect.get(); 553  } 从上面可以看到构造出来的Dialect对象存放在MLIRContextImpl的loadedDialects容器中类型DenseMapStringRef, std::unique_ptrDialect。同样MLIRContext也提供这些函数获取指定方言的Dialect对象getOrLoadDialect()loadDialect()等。比如Toy例子代码有这样的代码片段来构建自己的方言对象 int dumpMLIR() { mlir::MLIRContext context(/*loadAllDialects*/false); // Load our Dialect in this MLIR Context. context.getOrLoadDialectmlir::toy::ToyDialect(); identifiers 是MLIRContextImpl里有类型为llvm::StringMapPointerUnionDialect *, MLIRContext *, llvm::BumpPtrAllocator 的容器。MLIR里的标识符是带有上下文前缀或方言前缀的以“.”分隔identifiers容器就是关联标识符与其所在上下文对象或方言对象的一个操作在创建时首先假设它在一个上下文参考Identifier::get()上面537行的for循环检查是否已经创建了具有这个方言名的上下文对象如果是把它替换为对应的方言对象。 5.3.2.1. 方言接口 接下来通过DialectRegistry::registerDelayedInterfaces()向MLIRContextImpl注册方言的接口。这里“延迟接口”的意思是只在方言载入或创建时才注册接口。 106  void DialectRegistry::registerDelayedInterfaces(Dialect *dialect) const { 107    auto it interfaces.find(dialect-getTypeID()); 108    if (it interfaces.end()) 109      return; 110  111    // Add an interface if it is not already present. 112    for (const auto kvp : it-getSecond().dialectInterfaces) { 113      if (dialect-getRegisteredInterface(kvp.first)) 114        continue; 115      dialect-addInterface(kvp.second(dialect)); 116    } 117  118    // Add attribute, operation and type interfaces. 119    for (const auto kvp : it-getSecond().objectInterfaces) 120      kvp.second(dialect-getContext()); 121  } 方言可用的接口都保存在DialectRegistry类型为DenseMapTypeID, DelayedInterfaces的interfaces容器中其中DelayedInterfaces是DialectRegistry里这样的一个嵌套定义 283  struct DelayedInterfaces { 284      /// Dialect interfaces. 285      SmallVectorstd::pairTypeID, DialectInterfaceAllocatorFunction, 2 286          dialectInterfaces; 287      /// Attribute/Operation/Type interfaces. 288      SmallVectorstd::pairTypeID, ObjectInterfaceAllocatorFunction, 2 289          objectInterfaces; 290    }; 在下面我们会看到方言除了自己的接口还支持操作/类型/属性的外部模式接口289行的objectInterfaces是存放这些操作接口的地方。这两个容器用到这两个定义 30  using DialectInterfaceAllocatorFunction 31      std::functionstd::unique_ptrDialectInterface(Dialect *); 32  using ObjectInterfaceAllocatorFunction std::functionvoid(MLIRContext *); 顾名思义这两个std::function封装的方法用于创建接口对象在上面115与120行它们被调用来创建具体的接口对象。Dialect的addInterface()将生成的接口对象保存在registeredInterfaces容器中类型DenseMapTypeID, std::unique_ptrDialectInterface。而120行处创建的接口对象实际上保存在对应操作/类型/属性抽象对象的容器中下面会看到。
http://www.pierceye.com/news/96287/

相关文章:

  • seo站外推广如何用wampp 做网站
  • 怎样用手机做网站中企动力百度百科
  • 哪些网站可以做任务挣钱免费app软件
  • 国内简约网站平潭县机场建设网站
  • wordpress 全站通知wordpress怎样打开速度快
  • 广州市建设职业培训学校网站移除wordpress版本
  • 如何申请一个网站 新网动画制作大师
  • 动易后台 网站统计调查 报表类型怎样使用手机相册备份网站源码
  • 做网站放到百度上需要什么查看wordpress使用什么主题
  • 深圳企业网站seo郑州汉狮专业做网站公司
  • 广东网站建设多少钱辛集专业网站建设
  • 怎样做网站公司的销售小程序推广计划怎么赚钱
  • 网站开发文档编写wordpress小说站群
  • 南宁网站开发推广网站html模板下载
  • 网络编辑的网站建设题二手域名交易平台
  • 定制网站开发商业计划书贵南县网站建设公司
  • 如何免费发布个人网站网站项目需求分析
  • 太原免费网站建设网站开发合作协议书
  • 深圳龙华做网站上海响应式网站制作公司
  • 招投标 网站建设专业型网站和个人网站
  • 网站建设需要那些基础增城线上教学
  • 专注移动网站建设免费咨询电脑维修
  • 六里桥做网站公司惠州做网站 百度优化
  • 做网站怎么选择上市公司wordpress 进销存
  • 做视频网站用哪个模板昆明贤邦网站建设
  • 自建网站工具wordpress仿内涵段子
  • 做推广最好的网站是哪个菜鸟网站建设
  • 首钢建设公司网站微信网站怎么做的好处
  • 西安网站开发费用网站即将 模板
  • 个人做商业网站需要什么热门网站建设代理