Relay Arm® 计算库集成

介绍

Arm 计算库(ACL)是一个开源项目,它为 Arm CPU 和 GPU 提供了加速内核。目前,集成将算子迁移到 ACL 以在库中使用手工制作的汇编程序例程。通过将选择算子从 Relay 计算图迁移到 ACL,可在此类设备上实现性能提升。

安装 Arm 计算库

安装 Arm 计算库前,了解要构建的架构非常重要。一种方法是使用 lscpu,并查找 CPU 的“模型名称”,然后,可以使用它通过在线查看来确定架构。

TVM 目前只支持 v21.08 版本的 ACL,构建和安装所需的库的推荐方法如下:

  • 使用位于docker/install/ubuntu_download_arm_compute_lib_binaries.sh 的脚本,为 target_lib 指定的架构和扩展下载 ACL 二进制文件,它们将安装到 install_path 表示的位置。

  • 或从 https://github.com/ARM-software/ComputeLibrary/releases 下载预构建的二进制文件。 使用此包时,要为所需的架构和扩展选择二进制文件,并确保它们对 CMake 可见:

cd <acl-prebuilt-package>/libmv ./<architecture-and-extensions-required>/* .

这两种情况都要将 USE_ARM_COMPUTE_LIB_GRAPH_EXECUTOR 设置为 ACL 包所在的路径。 CMake 会在 /path-to-acl/,/path-to-acl/lib 和 /path-to-acl/build 中查找所需的二进制文件。如何使用这些配置选项,请参阅下一小节。

使用 ACL support 构建

当前的实现在 CMake 中有两个单独的构建选项。这种拆分的原因是 ACL 不能在 x86 机器上使用。但是,我们仍希望在 x86 机器上编译 ACL runtime 模块。

  • USE_ARM_COMPUTE_LIB=ON/OFF - 启用此标志能添加对编译 ACL runtime 模块的支持。
  • USE_ARM_COMPUTE_LIB_GRAPH_EXECUTOR=ON/OFF/path-to-acl - 启用此标志将允许图执行器计算 ACL 迁移的函数。

这些标志可根据你的设置应用于不同的场景。例如,若要在 x86 机器上编译 ACL 模块,并通过 RPC 在远程 Arm 设备上运行,则需要在 x86 机器上设置 USE_ARM_COMPUTE_LIB=ON,在远程 AArch64 设备上设置 USE_ARM_COMPUTE_LIB_GRAPH_EXECUTOR=ON。

默认这两个选项都设置为 OFF。设置 USE_ARM_COMPUTE_LIB_GRAPH_EXECUTOR=ON 意味着 CMake 会在默认位置和 /path-to-tvm-project/acl/ 目录下搜索 ACL 二进制文件(参阅 https://cmake.org/cmake/help/v3.4/command/find_library.html)。若要设置搜索 ACL 的路径,可在 ON 的位置指定。

这些标志应在 config.cmake 文件中进行设置,如:

set(USE_ARM_COMPUTE_LIB ON)
set(USE_ARM_COMPUTE_LIB_GRAPH_EXECUTOR /path/to/acl)

使用

备注
此部分可能与 API 的更改不同步。

创建一个 Relay 计算图(单个算子或整个计算图),使得任何 Relay 计算图都可以作为输入。ACL 集成只会选择支持的算子进行迁移,而其他的将通过 TVM 计算。(本例用的是单个 max_pool2d 算子)。

import tvm
from tvm import relaydata_type = "float32"
data_shape = (1, 14, 14, 512)
strides = (2, 2)
padding = (0, 0, 0, 0)
pool_size = (2, 2)
layout = "NHWC"
output_shape = (1, 7, 7, 512)data = relay.var('data', shape=data_shape, dtype=data_type)
out = relay.nn.max_pool2d(data, pool_size=pool_size, strides=strides, layout=layout, padding=padding)
module = tvm.IRModule.from_expr(out)

为 ACL 的计算图进行注释和分区:

from tvm.relay.op.contrib.arm_compute_lib import partition_for_arm_compute_lib
module = partition_for_arm_compute_lib(module)

构建 Relay 计算图:

target = "llvm -mtriple=aarch64-linux-gnu -mattr=+neon"
with tvm.transform.PassContext(opt_level=3, disabled_pass=["AlterOpLayout"]):lib = relay.build(module, target=target)

导出模块:

lib_path = '~/lib_acl.so'
cross_compile = 'aarch64-linux-gnu-c++'
lib.export_library(lib_path, cc=cross_compile)

必须在 Arm 设备上运行推理。若在 x86 设备上编译,在 AArch64 上运行,则需要借助 RPC 机制(参考 RPC 机制的使用教程)。

dev = tvm.cpu(0)
loaded_lib = tvm.runtime.load_module('lib_acl.so')
gen_module = tvm.contrib.graph_executor.GraphModule(loaded_lib['default'](dev))
d_data = np.random.uniform(0, 1, data_shape).astype(data_type)
map_inputs = {'data': d_data}
gen_module.set_input(**map_inputs)
gen_module.run()

更多示例

以上示例仅展示了如何用 ACL 迁移单个 Maxpool2D 的基本示例。若要查看所有实现的算子和网络的更多示例,参阅 tests:tests/python/contrib/test_arm_compute_lib(可修改 test_config.json 来配置如何在 infrastructure.py 中创建远程设备,从而配置 runtime 测试的运行方式。

以 test_config.json 的配置为例:

  • connection_type - RPC 连接的类型。选项:local、tracker 和 remote。
  • host - 要连接的主机设备。
  • port - 连接时使用的端口。
  • target - 用于编译的 target。
  • device_key - 通过 tracker 连接时的设备密钥。
  • cross_compile - 连接非 arm 平台时交叉编译器的路径,例如 aarch64-linux-gnu-g++。
{"connection_type": "local","host": "127.0.0.1","port": 9090,"target": "llvm -mtriple=aarch64-linux-gnu -mattr=+neon","device_key": "","cross_compile": ""
}

支持的算子

Relay 节点备注
nn.conv2dfp32:Simple: nn.conv2d Composite: nn.pad?, nn.conv2d, nn.bias_add?, nn.relu?支持深度和普通卷积(内核为 3x3 或 5x5 且步幅为 1x1 或 2x2 时),不支持分组卷积。```
qnn.conv2duint8:Composite: nn.pad?, nn.conv2d, nn.bias_add?, nn.relu?, qnn.requantizeNormal支持深度和普通卷积(当内核为 3x3 或 5x5,步长为 1x1 或 2x2 时),不支持分组卷积。
nn.densefp32:Simple: nn.dense Composite: nn.dense, nn.bias_add?
qnn.denseuint8:Composite: qnn.dense, nn.bias_add?, qnn.requantize
nn.max_pool2dfp32, uint8
nn.global_max_pool2dfp32, uint8
nn.avg_pool2dfp32:Simple: nn.avg_pool2d uint8:Composite: cast(int32), nn.avg_pool2d, cast(uint8)
nn.global_avg_pool2dfp32:Simple: nn.global_avg_pool2d uint8:Composite: cast(int32), nn.avg_pool2d, cast(uint8)
power(of 2) + nn.avg_pool2d + sqrtL2 池化的一种特殊情况。fp32:Composite: power(of 2), nn.avg_pool2d, sqrt
reshapefp32, uint8
maximumfp32
addfp32
qnn.adduint8

备注
复合算子由映射到单个 Arm 计算库的算子组成。从 Arm 计算库的角度来看,可以将其视为单个融合算子。“?”是构成复合算子的一系列算子中的可选算子。

添加新算子

添加新算子需要修改多处,本节将分享需要修改的内容和位置,但不会深入探讨单个算子的复杂性(这个问题留给开发者思考)。

下面是要修改的几个文件:

  • python/relay/op/contrib/arm_compute_lib.py:定义了要用 op.register 装饰器迁移的算子——意味着注释 pass 认为此算子可迁移 ACL。
  • src/relay/backend/contrib/arm_compute_lib/codegen.cc:实现 Create[OpName]JSONNode 的方法;声明算子如何由 JSON 表示,可用来创建 ACL 模块。
  • src/runtime/contrib/arm_compute_lib/acl_runtime.cc:实现 Create[OpName]Layer 方法;定义如何用 JSON 表示来创建 ACL 函数;只定义了如何将 JSON 表示转换为 ACL API。
  • tests/python/contrib/test_arm_compute_lib:为给定的算子添加单元测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/650013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shell编程之循环语句与函数

一 echo命令 echo -n 表示不换行输出 echo -e 表示输出转义符 常用的转义符 二 date date查看当前系统时间 -d 你描述的日期&#xff0c;显示指定字符串所描述的时间&#xff0c;而非当前时间 %F 完整日期格式&#xff0c;等价于 %Y-%m-%d % T 时间&#xff08;24小时…

构建支持 gpu 的 jupyterlab docker 镜像

构建支持 gpu 的 jupyterlab docker 镜像 1. 创建 Dockerfile2. 构建镜像3. 启动 gpu-jupyter4. 访问 gpu-jupyter 1. 创建 Dockerfile 创建一个 Dockerfile 文件&#xff0c;内容如下 FROM docker.io/nvidia/cuda:12.2.2-cudnn8-runtime-ubuntu22.04ENV DEBIAN_FRONTENDnoni…

JAVA和Go的不解之缘

JAVA和Go的不解之缘 Java和Go是两种不同的编程语言&#xff0c;它们在语法、特性和设计理念上存在一些明显的异同之处。 1. 语法和特性&#xff1a; Java是一种面向对象的语言&#xff0c;而Go则是一种面向过程的语言。Java拥有类、继承、接口等传统的面向对象特性&#xff…

Hadoop与Spark横向比较【大数据扫盲】

大数据场景下的数据库有很多种&#xff0c;每种数据库根据其数据模型、查询语言、一致性模型和分布式架构等特性&#xff0c;都有其特定的使用场景。以下是一些常见的大数据数据库&#xff1a; 1. **NoSQL 数据库**&#xff1a;这类数据库通常用于处理大规模、非结构化的数据。…

1.26学习总结

连通性判断 DFS连通性判断步骤&#xff1a; 1.从图上任意一点u开始遍历&#xff0c;标记u已经走过 2.递归u的所有符合连通条件的邻居点 3.递归结束&#xff0c;找到了的所有与u的连通点&#xff0c;就是一个连通块 4.然后重复这个步骤找到所有的连通块 BFS连通性判断步骤…

linux 查看zookeeper server运行版本号

zookeeper版本查看运行命令&#xff1a;echo stat|nc localhost 2181 显示如下图所示&#xff1a; Zookeeper version: 3.4.5-cdh6.3.2--1, built on 11/08/2019 13:15 GMT Clients: /127.0.0.1:44814[0](queued0,recved1,sent0) Latency min/avg/max: 0/0/0 Received: 9 Se…

MySQL如何避免全表扫描?

MySQL如何避免全表扫描&#xff1f; 这篇文章解释了何时以及为什么MySQL会执行全表扫描来解析查询&#xff0c;以及如何避免在大型表上进行不必要的全表扫描。 何时会发生全表扫描 MySQL使用全表扫描&#xff08;在EXPLAIN输出中的type列显示为ALL&#xff09;来解析查询的几…

防火墙的NAT

目录 1. NAT 概念解析 2. 配置NAT策略&#xff1a; 1. NAT 概念解析 静态NAT --- 一对一 动态NAT --- 多对多 NAPT --- 一对多的NAPT --- easy ip --- 多对多的NAPT 服务器映射 源NAT --- 基于源IP地址进行转换。我们之前接过的静态NAT&#xff0c;动态NAT&#xff0c;NAPT都属…

呼吸机电机控制主控MCU方案

呼吸机是一种能代替、控制或改变人的正常生理呼吸&#xff0c;增加肺通气量&#xff0c;改善呼吸功能&#xff0c;减轻呼吸功消耗&#xff0c;节约心脏储备能力的装置。呼吸机连接一条管子到患者的嘴或鼻子&#xff0c;氧气量可以通过监视器加以控制。 基于灵动微控制器的呼吸…

*【艺恩娱数】Python爬虫+数据分析可视化中国影院票房*¶

文章目录 一、记得登入才能看到所有的数据二、使用步骤艺恩数据可视化艺恩影院票房Top10艺恩影院票房销售额对比艺恩影院票房省份人次分析艺恩影院场次top10榜单 这个里面的影院名称&#xff0c;省份&#xff0c;城市&#xff0c;票房&#xff0c;场次&#xff0c;人次&#xf…

Map转成String,String 转换成Map

一、使用场景 把一个map转换成json字符串后存放在Redis中&#xff0c;然后在redis中取出json字符串&#xff0c;再把字符串转变成原来的Map 二、具体实现 1.1 Map转成String 这里使用是阿里巴巴fastjson Map<String, Object> reportData dssDashboardService.getRep…

ESXI 本地和虚拟机之间可以自由复制和粘贴

文章目录 ESXI 本地和虚拟机之间可以自由复制和粘贴 ESXI 本地和虚拟机之间可以自由复制和粘贴 web访问esxi&#xff0c;然后&#xff1a; 1、右击新建的虚拟机&#xff0c;确保是在关机状态下&#xff0c;点击编辑设置 2. 找到 虚拟机选项→高级→常规→配置参数 3、点击添加…

Unity3d C#实现三维场景中图标根据相机距离动态缩放功能

前言 如题的需求&#xff0c;其实可以通过使用UI替代场景中的图标来实现&#xff0c;不过这样UI的处理稍微麻烦&#xff0c;而且需要在图标上添加粒子特效使用SpriteRender更方便快捷。这里就根据相机离图标的位置来计算图标的缩放大小即可。这样基本保持了图标的大小&#xf…

Vulnhub靶场DC-3

本机192.168.223.128 靶机192.168.223.139 目标发现nmap -sP 192.168.223.0/24 端口扫描nmap -p- 192.168.223.139 之开启了一个80端口 看一下是什么服务 nmap -sV -p- -A 192.168.223.139是一个apache服务&#xff0c;joomla模板 看一下web 没什么有用信息。 扫描一下后台…

华为HCIP Datacom H12-831 卷18

判断题 1、对于同一个MAC地址,手工配置的MAC表项优先级高于动态的表项,某二层报文的源MAC地址已经绑定在了交换机的GEO/0/1接口,当交换机从GEO/0/2收到该报文时,会丢弃该报文 A 对 B 错 正确答案 A 解析:为了提高接口安全性,网络管理员可手工在MAC地址表中加入特定M…

银行数据仓库体系实践(3)--数据架构

狭义的数据仓库数据架构用来特指数据分布&#xff0c;广义的数据仓库数据架构还包括数据模型、数据标准和数据治理。即包含相对静态部分如元数据、业务对象数据模型、主数据、共享数据&#xff0c;也包含相对动态部分如数据流转、ETL、整合、访问应用和数据全生命周期管控治理。…

在 Vue 项目中,可以通过设置不同的环境变量来区分不同的环境,例如本地开发环境、测试环境和生产环境。以下是设置环境变量的步骤:

1、在src下新建三个文件夹 &#xff08;.env.local、.env.test 和 .env.prod&#xff09; 2、配置信息 .env.local VUE_APP_ENVlocal VUE_APP_API_URLhttp://localhost:8080.env.test VUE_APP_ENVtest VUE_APP_API_URLhttp://124.220.110.203:9090/ .env.prod VUE_APP_…

Java中实现线程的两种方式

实现线程的第一种方式&#xff1a; 编写一个类&#xff0c;直接继承java.lang.Thread,重写run方法 怎么创建线程对象&#xff1f; new就行了 怎么启动线程呢&#xff1f; 调用线程对象的start()方法 注意&#xff1a;方法体中的代码永远都是自上而下的顺序依次逐行执行。 以下…

Android源码设计模式解析与实战第2版笔记(一)

第一章 走向灵活软件之路 — 面向对象的六大原则 优化代码的第一步 — 单一职责原则 单一职责原则的英文名称是Single Responsibility Principle&#xff0c;缩写是SRP。 SRP&#xff1a;就一个类而言&#xff0c;应该仅有一个引起它变化的原因。 一个类中应该是一组相关性很…

Redis创建集群

主要内容 搭建redis集群 能力目标 搭建redis集群 一 应用场景 为什么需要redis集群&#xff1f; 当主备复制场景&#xff0c;无法满足主机的单点故障时&#xff0c;需要引入集群配置。 一般数据库要处理的读请求远大于写请求 &#xff0c;针对这种情况&#xff0c;我们优…