#nvbit #gpgpu #ffi #nvidia

nvbit-rs

用于使用NVIDIA NVBIT二进制插桩库的惯用库

29 个版本

0.0.38 2023年10月10日
0.0.35 2023年9月8日
0.0.32 2023年7月29日
0.0.19 2023年3月22日
0.0.6 2022年11月28日

#86 in Unix API

Download history 158/week @ 2024-03-21 635/week @ 2024-03-28 458/week @ 2024-04-04 477/week @ 2024-04-11 442/week @ 2024-04-18 5/week @ 2024-04-25 1/week @ 2024-05-16 2/week @ 2024-05-23

4,204 个月下载量

自定义许可协议

1.5MB
3.5K SLoC

Rust 2K SLoC // 0.0% comments CUDA 1.5K SLoC // 0.4% comments

nvbit-rs

试用一下
make -j -B -C test-apps/
# build the mem trace example tracer
cargo build --release -p mem_trace

# trace a sample application
LD_PRELOAD=./target/release/libmem_trace.so ./test-apps/vectoradd/vectoradd 100

完成

  • 实现 messagepack 和 json 跟踪转储
  • 不工作:清理 nvbit api,使其在 nvbit-rs 中管理上下文,钩子只是函数
Accelsim 参考
make -B -j -C ./tracer_nvbit
LD_PRELOAD=./tracer_nvbit/tracer_tool/tracer_tool.so ./nvbit-sys/nvbit_release/test-apps/vectoradd/vectoradd

这将生成以下文件:./tracer_nvbit/tracer_tool/traces/kernelslist./tracer_nvbit/tracer_tool/traces/stats.csv

我们的实现
cargo build --release
make -B -j -C ./examples/accelsim
LD_PRELOAD=./target/release/libaccelsim.so ./test-apps/vectoradd/vectoradd 100
LD_PRELOAD=./target/release/libmem_trace.so ./test-apps/vectoradd/vectoradd 100
docker build --platform linux/amd64 -t builder .
docker run --rm -i -v "$PWD":/src -v "$PWD"/buildcache:/cache builder cargo build
nvcc -D_FORCE_INLINES -dc -c -std=c++11 -I../nvbit_release/core -Xptxas -cloning=no -Xcompiler -w  -O3 -Xcompiler -fPIC tracer_tool.cu -o tracer_tool.o

nvcc -D_FORCE_INLINES -I../nvbit_release/core -maxrregcount=24 -Xptxas -astoolspatch --keep-device-functions -c inject_funcs.cu -o inject_funcs.o

nvcc -D_FORCE_INLINES -O3 tracer_tool.o inject_funcs.o -L../nvbit_release/core -lnvbit -lcuda -shared -o tracer_tool.so

现在是引入工作区的好时机,使示例成为带有 cargo.toml 的单独 crate,通过 build.rs 按示例编写自定义跟踪内核,这样我们可能最终会包含符号

  • 一种可能的方法是提供一个包装器,将其复制到 cxx::Vec<CUfuncton> 中,我想(参见 此示例

  • 由于我们是跟踪,并且这需要在每个未见过的函数上执行,这种复制开销是不可接受的

    • TODO:找出它被调用的频率,并可能仍然执行并测量
      • 更新:get_related_functions 只调用一次,尝试在 rust 中执行
  • 另一种方法:仅从通道接收内容,一个简单的结构...

    • 如果这样可行:我们如何决定使用哪个跟踪函数
      • (因为我们不能在Rust中编写新的函数)
  • 想办法通过使用命名空间来重用相同的nvbit名称?

  • 或者将调用封装在Rust中,调用 ffi::* 函数。

  • 重要观察

    • 我几乎放弃使用 cxx,因为它只给我 Unsupported type 错误
    • 我没有在 ffi 模块中导入 cxx::UniquePtrcxx::CxxVector,所以我假设我需要使用 cxx:: 来引用类型。
    • 它们在文档中没有这样做,但在顶级模块中使用了它们...
    • 结果你需要省略 cxx:: 前缀,因为这全是宏魔法...

完成

  • 我们必须以某种方式将CUDA注入函数和 nvbit_tool.h 包含到二进制文件中。
    • 也许可以在构建脚本中静态编译它们
    • 然后与 nvbit-sys 包进行链接
    • 然后,应该调用 nvbit_at_init - 希望如此

示例

当前目标是获取一个用Rust编写的跟踪器的工作示例。使用方法应该是

# install lld
sudo apt-get install -y lld
# create a shared dynamic library that implements the nvbit hooks
cargo build -p accelsim
# run the nvbit example CUDA application with the tracer
LD_PRELOAD=./target/debug/libaccelsim.so nvbit-sys/nvbit_release/test-apps/vectoradd/vectoradd

备注

检查已安装的clang版本

apt list --installed | grep clang

当运行 clang nvbit.h 时,它还抱怨缺少 cassert。使用 -std=c++11 -I$(NVBIT_PATH)

是 C++ STL,所以我们需要: clang++ -std=c++11 nvbit.h

bindgen 与 C++ 代码配合得不太好,请参阅 这里

我们需要一些 clang 东西,这样 bindgen 才能找到 #include <cassert>

我们还需要包含 nvbit.hnvbit_tool.h 和注入的跟踪函数,这需要编译和链接到二进制文件的 .cu 文件。

这个示例 展示了如何编译和链接 .cucc 包。

确保 nvbit 的 C 函数钩子在共享库中没有被破坏

nm -D ./target/debug/examples/libtracer.so
nm -D ./target/debug/build/nvbit-sys-08fdef510bde07a0/out/libinstrumentation.a

问题:我们需要在二进制文件中提供 instrument_inst 函数,就像示例中一样

nm -D /home/roman/dev/nvbit-sys/tracer_nvbit/tracer_tool/tracer_tool.so | grep instrument

# for a static library:
nm --debug-syms target/debug/build/accelsim-a67c1762e4619dad/out/libinstrumentation.a | grep instrument

目前,它没有 :(

确保我们进行了静态链接

ldd ./target/debug/examples/libtracer.so

检查 cxx 生成的包含文件

tre target/debug/build/nvbit-sys-*/out/cxxbridge/

依赖关系

~0.7–5.5MB
~92K SLoC