首页 > 其他分享 >TVM交叉编译RPC

TVM交叉编译RPC

时间:2023-07-24 19:11:38浏览次数:35  
标签:tvm remote target TVM 编译 RPC func 远程

Cross Compilation and RPC

本文将介绍交叉编译以及TVM通过RPC在远程设备上执行。

通过交叉编译和RPC,可以在本地机器上编译程序,然后在远程设备上运行。这在远程设备的资源有限时十分重要,例如Rasberry Pi和移动平台,本文将介绍Rasberry Pi的CPU例子和Firefly-RK3399的OpenCL例子

在设备上构建TVM Runtime

第一步是在远程设备上构建TVM runtime

因为我们在本地机器上编译,远程设备只用来执行构建好的代码,所以只需要在远程设备上构建TVM runtime。

git clone --recursive https://github.com/apache/tvm tvm
cd tvm
make runtime -j2

成功构建runtime后,需要设置环境变量,修改~/.bashrc,假定TVM的目录是~/tvm

export PYTHONPATH=$PYTHONPATH:~/tvm/python

更新环境变量

source ~/.bashrc

在设备上启动RPC服务器

在远程设备运行代码,例如Rasberry Pi,启动RPC服务器

python -m tvm.exec.rpc_server --host 0.0.0.0 --port=9090

如果有如下提示,则RPC已经在设备上成功启动

INFO:root:RPCServer: bind to 0.0.0.0:9090

在本地机器上定义并交叉编译kernel

这里使用有LLVM的TVM,首先在本地机器定义一个简单的kernel

import numpy as np

import tvm
from tvm import te
from tvm import rpc
from tvm.contrib import utils

n = tvm.runtime.convert(1024)
A = te.placeholder((n,), name="A")
B = te.compute((n,), lambda i: A[i] + 1.0, name="B")
s = te.create_schedule(B.op)

然后交叉编译,目标应该是llvm -mtriple=armv7l-linux-gnueabihf,这是Rasberry Pi 3B的选项,不过我们这里使用llvm作为示例。

local_demo = True

if local_demo:
    target = "llvm"
else:
    target = "llvm -mtriple=armv7l-linux-gnueabihf"

func = tvm.build(s, [A, B], target=target, name="add_one")
# save the lib at a local temp folder
temp = utils.tempdir()
path = temp.relpath("lib.tar")
func.export_library(path)

真实环境中,需要将local_demo设置为False,然后在build中修改target为对应的设备,例如Rasberry Pi 3B使用llvm -mtriple=armv7l-linux-gnueabihf,RK3399使用llvm -mtriple=aarch64-linux-gnu

通常,可以通过在目标设备上运行gcc -v查看Target

通过RPC远程启动CPU kernel

首先从远程设备获取RPC会话

if local_demo:
    remote = rpc.LocalSession()
else:
    # The following is my environment, change this to the IP address of your target device
    host = "10.77.1.162"
    port = 9090
    remote = rpc.connect(host, port)

上传lib到远程设备,然后调用本地编译器重新链接它们,现在func是一个远程的module对象

remote.upload(path)
func = remote.load_module("lib.tar")

# create arrays on the remote device
dev = remote.cpu()
a = tvm.nd.array(np.random.uniform(size=1024).astype(A.dtype), dev)
b = tvm.nd.array(np.zeros(1024, dtype=A.dtype), dev)
# the function will run on the remote device
func(a, b)
np.testing.assert_equal(b.numpy(), a.numpy() + 1)

当需要评估远程设备上kernel的性能时,需要避免提前网络的影响,time_evaluator将返回远程函数,提前运行了数次,排除网络的影响

time_f = func.time_evaluator(func.entry_name, dev, number=10)
cost = time_f(a, b).mean
print("%g secs/op" % cost)

输出

1.187e-07 secs/op

通过RPC远程启动OpenCL Kernel

对于远程OpenCL设备,工作流大部分都是相同的,可以定义kernel,上传文件,然后通过RPC运行

cp cmake/config.cmake .
sed -i "s/USE_OPENCL OFF/USE_OPENCL ON/" config.cmake
make runtime -j4

下面的函数展示如何远程运行OpenCL kernel

def run_opencl():
    # NOTE: This is the setting for my rk3399 board. You need to modify
    # them according to your environment.
    opencl_device_host = "10.77.1.145"
    opencl_device_port = 9090
    target = tvm.target.Target("opencl", host="llvm -mtriple=aarch64-linux-gnu")

    # create schedule for the above "add one" compute declaration
    s = te.create_schedule(B.op)
    xo, xi = s[B].split(B.op.axis[0], factor=32)
    s[B].bind(xo, te.thread_axis("blockIdx.x"))
    s[B].bind(xi, te.thread_axis("threadIdx.x"))
    func = tvm.build(s, [A, B], target=target)

    remote = rpc.connect(opencl_device_host, opencl_device_port)

    # export and upload
    path = temp.relpath("lib_cl.tar")
    func.export_library(path)
    remote.upload(path)
    func = remote.load_module("lib_cl.tar")

    # run
    dev = remote.cl()
    a = tvm.nd.array(np.random.uniform(size=1024).astype(A.dtype), dev)
    b = tvm.nd.array(np.zeros(1024, dtype=A.dtype), dev)
    func(a, b)
    np.testing.assert_equal(b.numpy(), a.numpy() + 1)
    print("OpenCL test passed!")

总结

介绍了TVM的RPC特性和交叉编译

  • 在远程设备上启动RPC服务器
  • 对目标设备配置,在本地机器进行交叉编译
  • 通过RPC API远程上传和运行kernel

标签:tvm,remote,target,TVM,编译,RPC,func,远程
From: https://www.cnblogs.com/ddl789/p/17578086.html

相关文章

  • 编译期处理
    默认构造器publicclasstest{}编译classpublicclasstest{ publictest(){ super(); }}自动拆装箱泛型集合取值foreach循环枚举类try-with-resources匿名内部类......
  • 【idea编译问题】可以找打对应的class 但是 idea 提示 java: 找不到符号
    可以找打对应的class但是idea提示java:找不到符号这个问题有的时候,可能是lombock引起的,可以在maven编译的时候填写-Djps.track.ap.dependencies=false......
  • mpc库问题导致gcc编译失败
    使用mpc-1.3.0编译gcc-13.1.0,执行gcc的configure时遇到如下错误:checkingforthecorrectversionofgmp.h...yescheckingforthecorrectversionofmpfr.h...yescheckingforthecorrectversionofmpc.h...noconfigure:error:BuildingGCCrequiresGMP4......
  • 【Boost】Windows端使用 MSVC14.2 编译 Boost 并在 CMake 项目中使用
    Write2023.7.24关于boost在Windows下的使用gcc安装与CLion的配置,能够查到的英文资料都比较少,踩过坑后记录一下。MinGW安装BoostBoostDownload:https://www.boost.org/users/download/下载并解压在某个没有中文路径下的目录中在开始编译操作之前请把gcc添......
  • m基于OFDM+QPSK和LDPC编译码通信链路matlab性能仿真,包括Costas载波同步和gardner定时
    1.算法仿真效果matlab2013b仿真结果如下:      2.算法涉及理论知识概要        基于OFDM+QPSK和LDPC编码的通信链路是一种常用的数字通信系统,用于实现高速、可靠的数据传输。该系统结合了正交频分复用(OFDM)、四相移键控(QPSK)调制和低密度奇偶校验(LDPC)编码......
  • 在Windows上编译Pytorch 源码
    在Windows上编译PyTorch源码作为一名经验丰富的开发者,我将向你介绍如何在Windows上编译PyTorch源码。编译PyTorch源码可以帮助你获得更多的灵活性,以及对PyTorch内部机制的更深入的了解。下面是整个过程的步骤:步骤操作1安装Git2安装CMake3安装Python4克隆Py......
  • 3步带你搞定华为云编译构建CodeArts Build “新手村任务”
    华为云编译构建(CodeArtsBuild)基于云端大规模并发加速,为客户提供高速、低成本、配置简单的混合语言构建能力,帮助客户缩短构建时间,提升构建效率。本文将给各位开发者带来华为云CodeArtsPipeline的手把手初级教学,让没有接触过的开发者能够轻松上手体验。【操作步骤】体验准备:注......
  • STM8S编译错误unable to allocate space for sections/blocks with a total
    STM8S编译错误unabletoallocatespaceforsections/blockswithatotal#欢迎使用Markdown编辑器笔者用IARforSTM8开发碰到很多奇怪的问题,都是因为优化等级引起的首先看这个用dubug编译错误提示:unabletoallocatespaceforsections/blockswithatotalestimatedm......
  • 《Spring6核心源码解析》已完结,涵盖IOC容器、AOP切面、AOT预编译、SpringMVC,面试杠杠
    作者:冰河星球:http://m6z.cn/6aeFbs博客:https://binghe.gitcode.host文章汇总:https://binghe.gitcode.host/md/all/all.html源码地址:https://github.com/binghe001/spring-annotation-book沉淀,成长,突破,帮助他人,成就自我。大家好,我是冰河~~提起Spring,可以这么说,Spring几乎......
  • 在windows平台使用Visual Studio 2017编译动态库并使用
    使用VSstdio制作顺序表的库文件.lib与.dll区别lib是编译时需要的dll是运行时需要的1、新建头文件和源文件SeqList.h//SeqList.h#ifndefSEQLIST_H__#defineSEQLIST_H__#defineN10typedefintSLDataType;typedefstructSeqList{ SLDataTypedata[N]......