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

手搓一个CUDA JIT编译器

文章目录

  • 1. 前言
  • 2. 背景介绍
  • 3. 示例
  • 4. Kernel Cache

1. 前言

最近在看一些开源项目,CUDA通过pybind绑定到python接口时,常常需要设计一个JIT编译器来满足对kernel的即时编译调用。受此启发,决定一探究竟,这篇文章将教会搓一个JIT编译组件

2. 背景介绍

要实现一个CUDA JIT编译器,至少有两条路线:
在这里插入图片描述

  • 线路1:使用nvcc,需要先将kernel字符串写入到临时文件kernel.cu中,再使用nvcc -cubin 编译出cubin file
  • 线路2:使用nvrtc, 则可以直接使用字符串,通过nvrtcCompileProgram编译,并使用nvrtcGetCUBIN获得cubin data,写入cubin file

3. 示例

假设我们要运行的Kernel函数是:

const kernelStr = "__global__ void empty() {}";

使用线路1:
先将字符写入kernel.cu

nvcc -dc -cubin --gpu-architecture=sm_90 -O3 kernel.cu -o kernel.cubin

使用线路2:

#include <nvrtc.h>#include <assert.h>
#include <fstream>
#include <sstream>
#include <string.h>
#include <string>
#include <vector>const char kernelStr[] = "__global__ void empty() {}";int main() {const char flags[] = "--gpu-architecture=sm_90";const char cubin_path[] = "kernel.cubin";std::istringstream iss(flags);std::vector<std::string> options;std::string option;while (iss >> option)options.push_back(option);std::vector<const char *> option_cstrs;for (const auto &opt : options)option_cstrs.push_back(opt.c_str());nvrtcProgram program;nvrtcCreateProgram(&program, kernelStr, "kernel.cu", 0, nullptr, nullptr);const auto &compile_result = nvrtcCompileProgram(program, static_cast<int>(option_cstrs.size()), option_cstrs.data());size_t log_size;nvrtcGetProgramLogSize(program, &log_size);if (compile_result != NVRTC_SUCCESS) {if (log_size > 1) {std::string compilation_log(log_size, '\0');nvrtcGetProgramLog(program, compilation_log.data());printf("NVRTC log: %s\n", compilation_log.c_str());}nvrtcDestroyProgram(&program);return 1;}size_t cubin_size;nvrtcGetCUBINSize(program, &cubin_size);std::string cubin_data(cubin_size, '\0');nvrtcGetCUBIN(program, cubin_data.data());std::ofstream out(cubin_path, std::ios::binary);nvrtcDestroyProgram(&program);out.write(cubin_data.data(), cubin_data.size());return 0;
}

编译是需要加入-I/usr/local/cuda/include -lnvrtc -L/usr/local/cuda/lib64 来保证正确link rtc的library和找到头文件

4. Kernel Cache

可以看出一个问题,我们每次运行时,都会去编译这个cubin函数,那么有什么方式可以优化这个操作呢?我们可以使用hash_map来将编译好的cubin file缓存起来,当第二次再次调用时,可以直接从hash_map中获取,从而实现zero compiler.

http://www.dtcms.com/a/520133.html

相关文章:

  • 网站引导页模板互联网公司排名全球
  • JDK 9 List.of(...)
  • 做一个vue3 v-model 双向绑定的弹窗
  • 为超过10亿条记录的订单表新增字段
  • 哪里做网站最便宜WordPress功能模块排版
  • 每日算法刷题Day78:10.23:leetcode 一般树7道题,用时1h30min
  • 薄膜测厚选CWL法还是触针法?针对不同厚度与材质的台阶仪技术选型指南
  • WPF-MVVM的简单入门(第一个MVVM程序)
  • blender拓扑建模教程
  • asp.net手机网站开发教程翻译网站建设方案
  • 佛山建设网站公司哪家好特斯拉ceo进厂拧螺丝
  • 如何做新网站保留域名wordpress基础
  • C# 实现 Modbus TCP 通信
  • 《Git:从入门到精通(七)——Git分支管理与协作开发实战》
  • 超越传统工具:利用Reddit发现关键词的独特视角与前沿方法
  • 数据结构——二叉搜索树深度解析
  • macOS 无法在根目录创建目录的原因与解决方案
  • 11.23 鸿蒙HTTP数据请求
  • 郑州网站建设最低价网址导航的意思
  • LOESS回归
  • 跨平台开发中的图形渲染:Canvas与View+CSS的性能分析与决策路径
  • 能源经济选题推荐:可再生能源转型政策如何提高能源韧性?基于双重机器学习的因果推断
  • 《R for Data Science (2e)》免费中文翻译 (第11章) --- Communication(1)
  • 生成式对抗网络 GAN:从零理解生成对抗网络的原理与魅力
  • 李宏毅机器学习笔记30
  • 做塑胶材料的网站深圳网站设计平台
  • 【设计模式】装饰器模式(Decorator)
  • 设计模式之:享元模式
  • android 图像显示框架二——流程分析
  • CentOS 10 系统安装