给自己记录一下,不一定对。每次去重写的时候又要忘记。
1.python部分
在gaussian_renderer/__init__.py
里面调用cuda写的rasterization,语句为:
from diff_gaussian_rasterization import GaussianRasterizationSettings, GaussianRasterizer
其中GaussianRasterizationSettings
定义了初始化一个类的参数,GaussianRasterizer是这个类,直接对应的是./submodules/diff-gaussian-rasterization/diff_gaussian_rasterization/__init__.py
中两个python类,class GaussianRasterizationSettings(NamedTuple)
和class GaussianRasterizer(nn.Module)
。
GaussianRasterizer
是一个正常的python class(继承nn.Module),包括了forward和自动backward,到这里都是熟悉的东西。
forward中调用了rasterize_gaussians
,rasterize_gaussians
又调用了_RasterizeGaussians
,_RasterizeGaussians
继承自torch.autograd.Function,要求自己写forward和backward,所以这个类下面开始有backward函数。backward函数和forward函数输入输出需要相对应,比如foward函数输出了color, radii
,则backward输入ctx, grad_out_color, _
也就是上下文信息和两个forward输出的变量的grad;forward输入了除ctx外9个变量,则backward返回9个梯度,不需要梯度的变量用None占位。
2.python和C++的桥梁
forward和backward中调用了_C.rasterize_gaussians
和_C.rasterize_gaussians_backward
,这是C函数,其桥梁在文件./submodules/diff-gaussian-rasterization/ext.cpp
中定义:
点击查看代码
#include <torch/extension.h>
#include "rasterize_points.h"
PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
m.def("rasterize_gaussians", &RasterizeGaussiansCUDA);
m.def("rasterize_gaussians_backward", &RasterizeGaussiansBackwardCUDA);
m.def("mark_visible", &markVisible);
}
意思是_C.rasterize_gaussians_backward
和rasterize_points.h中的C函数RasterizeGaussiansBackwardCUDA绑定,另外两对同理。
3.C++和CUDA部分(我分不清)
./submodules/diff-gaussian-rasterization/rasterize_points.cu
以及其.h文件定义了这三个C函数,做了一些变量初始化之类的工作,然后在RasterizeGaussiansCUDA和RasterizeGaussiansBackwardCUDA中分别使用了CudaRasterizer::Rasterizer
的forward和backward函数,这是一个CUDA类(写法和C++一样我写博客的时候所以没有区分)。
这个类在./submodules/diff-gaussian-rasterization/cuda_rasterizer/rasterizer.h
和同目录下的rasterizer_impl.h以及rasterizer_impl.cu中定义。核心是在backward和forward中分别使用的BACKWARD::render
和FORWARD::render
。以后者为例,是定义在同目录下forward.h和forward.cu。
FORWARD::render
中使用renderCUDA<NUM_CHANNELS> << <grid, block >> >
,这里开始才进入了CUDA并行计算。将image分为多个block,每个block分配一个进程;每个block里面的pixel分配一个进程。对于每个block只排序一次,认为block里面的pixel都被block中的所有gaussian影响且顺序一样。
在forward中,沿camray从前往后遍历gaussian,计算颜色累计值和透明度累计值,直到透明度累计超过1或者遍历完成,然后用背景色和颜色累计值和透明度累计值计算这个pixel的最终颜色。在backward中,遍历顺序与forward相反,从(之前记录下来的)最终透明度累计值和其对应的最后一个gaussian开始,从后往前算梯度。
./submodules/diff-gaussian-rasterization/cuda_rasterizer/config.h
中记录了render的颜色通道数和BLOCK的长宽。所以其实要render多种信息(比如深度,normal,透明度etc.)只要修改颜色通道数就可以并行render了,不用花串行那个时间,说的就是GaussianShader,很蠢。
4.其他
其它记录一下的小点:
1.只是修改常数值or函数头,也可以还有其他一些,总之如果不修改函数体的话,重新编译可能并不会有效。可以随便在函数体里面加一句printf("haha")之类的,编译然后再删掉然后再编译,才能起效果。比如修改config.h的颜色通道数就需要这样重新编译。(或者可能有强制重新编译的命令,只是我不知道,比较蠢)
2.TBA
其他很多应该也很有意思的,比如preprocess在做啥,比如排序在哪里怎么排的,因为还没用到所以还没读,等需要用读到的时候再更新(逃
标签:rasterization,Splatting,rasterize,gaussian,Gaussian,CUDA,forward,backward,gaussi From: https://www.cnblogs.com/zyx45889/p/18090482